?
avatar manojLondhe
manojLondhe
14 Mar 2018

Fatal error seen in many 3rd party extensions after upgrading to from J3.8.5 to J3.8.6

Nesting level too deep - recursive dependency? in joomla/libraries/joomla/event/dispatcher.php on line 198

Steps to reproduce the issue

  • Not seen with core Joomla extensions
  • For custom extensions code given in below triggers the error
Call Stack
#	Time	Memory	Function	Location
1	0.0003	380080	{main}( )	.../index.php:0
2	0.0198	1539376	Joomla\CMS\Application\SiteApplication->execute( )	.../index.php:49
3	0.0198	1539376	Joomla\CMS\Application\SiteApplication->doExecute( )	.../CMSApplication.php:204
4	0.1237	7498736	Joomla\CMS\Application\SiteApplication->dispatch( )	.../SiteApplication.php:233
5	0.1242	7530168	Joomla\CMS\Component\ComponentHelper::renderComponent( )	.../SiteApplication.php:194
6	0.1253	7621512	Joomla\CMS\Component\ComponentHelper::executeComponent( )	.../ComponentHelper.php:357
7	0.1255	7668696	require_once( 'joomla/components/com_example/example.php' )	.../ComponentHelper.php:382
8	0.1424	8556624	ExampleController->execute( )	.../example.php:138
9	0.1424	8556624	ExampleController->display( )	.../BaseController.php:710
10	0.1461	8981704	ExampleViewRecords->display( )	.../BaseController.php:672
11	0.1602	9508088	ExampleHelper->getItemId( )	.../view.html.php:213
12	0.1602	9508536	Joomla\CMS\Application\SiteApplication->__construct( )	.../helper.php:62
13	0.1602	9508568	Joomla\CMS\Application\SiteApplication->__construct( )	.../SiteApplication.php:66
14	0.1609	9521096	Joomla\CMS\Application\SiteApplication->loadSession( )	.../CMSApplication.php:144
15	0.1609	9521472	Joomla\CMS\Application\SiteApplication->registerEvent( )	.../CMSApplication.php:736
16	0.1609	9521472	JEventDispatcher->register( )	.../BaseApplication.php:88
17	0.1609	9521848	JEventDispatcher->attach( )	.../dispatcher.php:104

The function from custom component getItemId has code like

$app = JFactory::getApplication();

if ($app->issite())
{
	$JSite = new JSite;
	$menu  = $JSite->getMenu();
	$items = $menu->getItems('link', $link);

The line $JSite = new JSite; seems to to trigger recursion mentioned in the error.

System information

Joomla 3.8.6
Database Type | mysql
Database Version | 5.7.21-0ubuntu0.16.04.1
Database Collation | utf8_general_ci
Database Connection Collation | utf8mb4_general_ci
PHP Version | 7.0.28-1+ubuntu16.04.1+deb.sury.org+1
Web Server | Apache/2.4.29 (Ubuntu)

Additional information

avatar manojLondhe manojLondhe - open - 14 Mar 2018
avatar joomla-cms-bot joomla-cms-bot - change - 14 Mar 2018
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 14 Mar 2018
avatar manojLondhe manojLondhe - change - 14 Mar 2018
Title
[J3.8.6] Fatal error: Nesting level too deep - recursive dependency? in joomla/libraries/joomla/event/dispatcher.php on line 198
[J3.8.6] Fatal error: Nesting level too deep - recursive dependency in joomla/libraries/joomla/event/dispatcher.php
avatar manojLondhe manojLondhe - edited - 14 Mar 2018
avatar franz-wohlkoenig franz-wohlkoenig - change - 14 Mar 2018
Category Libraries
avatar manojLondhe manojLondhe - change - 14 Mar 2018
The description was changed
avatar manojLondhe manojLondhe - edited - 14 Mar 2018
avatar mbabker
mbabker - comment - 14 Mar 2018

At least in the case of this extension, the code is wrong.

$app = JFactory::getApplication();

if ($app->isSite()) {
    $menu = $app->getMenu();
    $items = $menu->getItems('link', $link);

    // Other stuff
}

There is no need to instantiate a new application class to get the menu data. Doesn't answer the potential recursive dependency problem, but fixing the extension code avoids that.

avatar manojLondhe manojLondhe - change - 14 Mar 2018
The description was changed
avatar manojLondhe manojLondhe - edited - 14 Mar 2018
avatar toto13009
toto13009 - comment - 14 Mar 2018

Same problem to me.
At this time, I have disabled language filter plugin and notice error disappears. I am waiting the next update.

avatar manojLondhe manojLondhe - change - 14 Mar 2018
The description was changed
avatar manojLondhe manojLondhe - edited - 14 Mar 2018
avatar manojLondhe manojLondhe - change - 14 Mar 2018
The description was changed
avatar manojLondhe manojLondhe - edited - 14 Mar 2018
avatar mbabker
mbabker - comment - 14 Mar 2018

Need more info to reproduce.

https://downloads.joomla.org is a multi-language website which has the language filter plugin enabled and this problem cannot be triggered on this site (it is in essence core Joomla plus Akeeba Release System and an extra system plugin specific for our addons). Which means there is some specific configuration or combination of extensions creating the problem.

On its own, the error message is not going to provide enough detailed information to troubleshoot anything. Detailed information such as stack traces, the data in the variables on the dispatcher line that is failing, and which check in that line is creating the message is going to be needed.

avatar toto13009
toto13009 - comment - 14 Mar 2018

How I have got this error?
I was working with joomla 3.8.5 and php 7.0.X. All was working perfectly without any trouble.
Yesterday to me, When the joomla 3.8.6 has been available in my joomla backend, I made the automatic update. But it didn't work. I downloaded the joomla update package for installation and the error appeared.
First, I was thinking it was a problem with php 7.0.X and I changed my php version to php 7.1.X (7.1.15), I made a new joomla automatic update and it did it (without any trouble), but the error was still there and impossible to get user page (easysocial) for example. I disabled language plugin filter and all works fine.

avatar franz-wohlkoenig franz-wohlkoenig - change - 14 Mar 2018
Status New Discussion
avatar Magisdn
Magisdn - comment - 14 Mar 2018

I my case disabling the "Language-Plugins" did not fix the problem.

avatar alikon
alikon - comment - 14 Mar 2018

can you test #19907

avatar revoka
revoka - comment - 14 Mar 2018

alikon I can confirm that #19907 solves the problem in my similar situation as described above.

avatar alikon
alikon - comment - 14 Mar 2018

happy that your issue is solved not happy because i still don't understand why this happens

avatar alikon
alikon - comment - 14 Mar 2018

did you use a multilingual site?
from what j version are you upgrading ?

avatar revoka
revoka - comment - 14 Mar 2018

I was trying to find a reason why all afternoon in my test setup.
I was upgrading from 3.8.5 and I am using a multilingual site.
Disabling the system languagefilter-plugin resolved the problem but left me with a non multilingual site.
So I think there has to be some connection with multiple languages setup.

avatar mbabker
mbabker - comment - 14 Mar 2018

So I think there has to be some connection with multiple languages setup.

It's going to be a specific combination of extensions if that is the case. As I pointed out earlier, our downloads site is a multi-language setup and is not experiencing this issue (the site is basically core Joomla plus Akeeba Release System plus a custom system plugin for the site). If it is indeed related to or caused by the language filter plugin, what configuration is the plugin set up to run with (perhaps there's a specific configuration that can trigger the issue but another configuration that won't)?

avatar jamield
jamield - comment - 14 Mar 2018

Just to add to this: I've experienced this issue on a site I look after and it does not use the multi-language plugin. I have however identified the custom plugin which was causing the issue.

I've got about half an hour spare so I'm going to see if I can narrow down the exact line of code...

avatar jamield
jamield - comment - 14 Mar 2018

Ok I've narrowed it down to a custom system plugin which had this code in a static function:
$Jsite = new JSite(); $menu = $Jsite->getMenu();

Changing to this solved it:
$app = JFactory::getApplication(); $menu = $app->getMenu();

That said, I have another site using the same plugin which hasn't broken.

avatar csthomas
csthomas - comment - 14 Mar 2018

It is very interesting, my observation
Go to 3.8.6 and apply this:

diff --git a/plugins/system/languagefilter/languagefilter.php b/plugins/system/languagefilter/languagefilter.php
index 9d5bf41b7d..2f9c01ff1f 100644
--- a/plugins/system/languagefilter/languagefilter.php
+++ b/plugins/system/languagefilter/languagefilter.php
@@ -174,7 +174,7 @@ class PlgSystemLanguageFilter extends JPlugin
         * @since   3.4
         */
        public function preprocessBuildRule(&$router, &$uri)
-       {
+       {$Jsite = new JSite(); $menu = $Jsite->getMenu();
                $lang = $uri->getVar('lang', $this->current_lang);
                $uri->setVar('lang', $lang);

It generate error on staging joomla.
After git stash; git checkout 3.8.5~1; git stash apply it works again.

avatar alikon
alikon - comment - 14 Mar 2018

gosh till now i'm investigating in a not multilanguage direction... confused

avatar mbabker
mbabker - comment - 14 Mar 2018

My feeling is it has nothing to do with WHERE the code is, it's just the simple fact of instantiating a new application that's doing it. Something tells me you could do (new JSite)->getMenu(); (new JSite)->getMenu(); in index.php and trigger it without running anything else too (as in something in at least the site application constructor is more than enough to trigger it).

avatar csthomas
csthomas - comment - 14 Mar 2018

The issue is generated by commit from #19687. I do not know why yet.

git checkout 3.8.6~12 - works
git checkout 3.8.6~11 - error

avatar mbabker
mbabker - comment - 14 Mar 2018

It's probably

$this->metadataManager = new MetadataManager($this, \JFactory::getDbo());
and the only thing I can think of to get around that is to not have the metadata manager as a class level property and just direct instantiate and run it when needed (only the checkSession method uses it). But then there's the question of whether it's going to also be a problem if in 4.0 we can get that to be an injectable dependency in the constructor since that's using a totally different event dispatching system.

avatar csthomas
csthomas - comment - 14 Mar 2018

Maybe instead of CMSApplication property ($this->metadataManager) it could be a Session property.

avatar mbabker
mbabker - comment - 14 Mar 2018

Wouldn't fly. The metadata manager's not part of the Session itself (nor should it be IMO) and then you really start getting into circular dependency potential.

For now you can just direct instantiate and run the MetadataManager when needed, for the app that's only in the checkSession method, but clearly we need to deal with the architectural dependency circle at some point (part of the problem is it all falls apart when you try to run

$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));
which shouldn't be part of the application but configured outside of it, not something we can do much about in the 3.x code).

avatar csthomas
csthomas - comment - 14 Mar 2018

For now you can just direct instantiate and run the MetadataManager when needed,

It is OK,

but may be we do not need a $this->app in MetadataManager class. We can use $app->config in MetadataManager constructor like $this->metadataManager = new MetadataManager($this->config, \JFactory::getDbo());.

avatar csthomas
csthomas - comment - 14 Mar 2018

Or better we can put only array of options as in other places.

$opton['clientId'] = ...
$option['shared_session'] = ...
$this->metadataManager = new MetadataManager(\JFactory::getDbo(), $options);
avatar mbabker
mbabker - comment - 14 Mar 2018

Thought about that. Need the client ID when shared sessions aren't active to fill the appropriate column for the metadata. So it's either a DI'd app instance in the constructor, a DI'd app instance in the createRecordIfNonExisting method that actually has all the app dependencies, or a dependency to JFactory::getApplication() to be able to call $app->getClientId().

avatar mbabker
mbabker - comment - 14 Mar 2018

Or better we can put only array of options as in other places.

I'd rather not. Unkeyed options arrays aren't great for DI and we usually do zero validation on these arrays (you really need something like joomla-framework/database#101 in all the places we have options arrays so that there's some form of API to validate those arrays and create some self documenting code describing what those arrays should be). If you're really going to create an options array, I'd rather the constructor signature be (\JDatabaseDriver $db, int $appClientId, bool $sharedSessionsActive) and pass each value as separate arguments.

avatar csthomas
csthomas - comment - 14 Mar 2018

I'd rather the constructor signature be (\JDatabaseDriver $db, int $appClientId, bool $sharedSessionsActive) and pass each value as separate arguments.

Magnificent. I like it the most.

avatar csthomas
csthomas - comment - 14 Mar 2018

For now you can just direct instantiate and run the MetadataManager when needed,

After thinking, I think that it also has its advantages. And could be joined with above.

avatar mbabker
mbabker - comment - 14 Mar 2018

For 3.x, I'd just change the checkSession method and not have the class member var. At least this way if you're writing something to work with it you can still do new MetadataManager(JFactory::getApplication(), JFactory::getDbo()) and not have to think too much about things.

In 4.0, with all the other architecture work ongoing, we can re-visit the manager's structure and where it exists by default.

avatar csthomas
csthomas - comment - 14 Mar 2018

So we have a solution.

avatar mbabker
mbabker - comment - 14 Mar 2018

Yep, #19912

avatar joomla-cms-bot joomla-cms-bot - change - 15 Mar 2018
Closed_By franz-wohlkoenig joomla-cms-bot
avatar joomla-cms-bot joomla-cms-bot - close - 15 Mar 2018
avatar franz-wohlkoenig franz-wohlkoenig - change - 15 Mar 2018
Status Discussion Closed
Closed_Date 0000-00-00 00:00:00 2018-03-15 06:39:31
Closed_By franz-wohlkoenig
avatar joomla-cms-bot
joomla-cms-bot - comment - 15 Mar 2018
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 15 Mar 2018

closed as having Pull Request #19912

Add a Comment

Login with GitHub to post a comment