No Code Attached Yet
avatar joeforjoomla
joeforjoomla
28 Jun 2022

Steps to reproduce the issue

Install whatever extension on Joomla 4.2, for example Acymailing, JEvents, etc

In more details, it seems that the class Joomla\CMS\Installer\Installer is now DatabaseAwareTrait and if an extension instantiate it in the install script as usual, it will be missing the setDatabase causing the B/C issue.
It's common that an install script also install other extensions such as plugins, modules, etc

Expected result

No errors

Actual result

Installation fails:
image

System information (as much as possible)

Joomla 4.2 Beta 2

avatar joeforjoomla joeforjoomla - open - 28 Jun 2022
avatar joomla-cms-bot joomla-cms-bot - change - 28 Jun 2022
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 28 Jun 2022
avatar joeforjoomla joeforjoomla - change - 28 Jun 2022
The description was changed
avatar joeforjoomla joeforjoomla - edited - 28 Jun 2022
avatar joeforjoomla joeforjoomla - change - 28 Jun 2022
The description was changed
avatar joeforjoomla joeforjoomla - edited - 28 Jun 2022
avatar brianteeman
brianteeman - comment - 28 Jun 2022

Almost certainly those extensions have only been set as compatible with 4.0 and 4.1

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

@brianteeman an extension has to be set compatible with Joomla 3 and Joomla 4 on the JED and it's supposed to be compatible with a whole major release without this kind of breaking changes between a minor release.

avatar brianteeman
brianteeman - comment - 29 Jun 2022

1. 4.2 is not releasd yet
2. This is nothing new. An extension has always been responsible with setting which version it is compatible with.
3. I might hav been confused with th targetversion in the update xml

avatar laoneo
laoneo - comment - 29 Jun 2022

I just tried to install JEvents on the latest 4.2 code and it worked. Can you test if they work with the latest changes from the 4.2-dev branch?

avatar laoneo
laoneo - comment - 29 Jun 2022

Acymailing failed with the first installation but a second one succeeded.

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

@laoneo the problem happens when an extension instantiate the class Joomla\CMS\Installer\Installer in the install script file without being aware that now it requires ->setDatabase() to inject the db object

avatar OctavianC
OctavianC - comment - 29 Jun 2022

Can confirm - new JInstaller now needs $installer->setDatabase($db); to work. Also, a world of pain comes up when calling the JInstaller to uninstall another extension from the uninstall script:

class com_testInstallerScript
{
	public function uninstall($parent)
	{
		$extension_id = 'some-other-extension';
		$installer = new JInstaller;
		$installer->setDatabase($db)
		$installer->uninstall('plugin', $extension_id);
	}
}

EDIT: got confused editing the wrong file, above works, so just setDatabase() is needed whenever a new JInstaller is created.

avatar laoneo
laoneo - comment - 29 Jun 2022

@laoneo the problem happens when an extension instantiate the class Joomla\CMS\Installer\Installer in the install script file without being aware that now it requires ->setDatabase() to inject the db object

When not available, then this should be set from the global db instance. As I said, can you try with the latest code changes from the 4.2-dev branch?

avatar laoneo
laoneo - comment - 29 Jun 2022

There should be a fallbck to the gloabl db instance when it is not set. But I need some kind of a stack trace as I can't reproduce the issue with the latest code from the 4.2-dev branch.

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022
avatar OctavianC
OctavianC - comment - 29 Jun 2022

same results with latest nightly.

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

Confirmed, same results with latest nightly https://developer.joomla.org/nightlies/Joomla_4.2.0-dev-Development-Full_Package.zip and the latest package of Acymailing attached used as an example

starter_v7.8.3_2022-06-29_09-48-10.tar.gz
image

avatar laoneo
laoneo - comment - 29 Jun 2022

I will have a look as it looks like there is something different between the branch and the build. I will report back as this should def. work without explicitly setting the database.

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

@laoneo thank you. Let me know if you need further informations or tests on my side

avatar OctavianC
OctavianC - comment - 29 Jun 2022

This is the line that's causing issues in starter_v7.8.3_2022-06-29_09-48-10.tar.gz

$installer = new JInstaller();
$installer->refreshManifestCache($extension->extension_id);
avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

@OctavianC that's not only the reason, it's enough to use the installer for example to install a plugin:

$pluginInstaller = new Installer ();
$pluginInstaller->install($path);
avatar OctavianC
OctavianC - comment - 29 Jun 2022

Yes, I've already figured that out. Can be fixed by using $installer->setDatabase($db) but a $db should be assumed by the code if not explicitly set.

I see that a36f76c has injected $db to every Installer object but that shouldn't have been needed as it's breaking compatibility

avatar joeforjoomla
joeforjoomla - comment - 29 Jun 2022

@OctavianC yes indeed this is exactly the point of this issue, as @laoneo said it should work in all cases. Let's @laoneo having a look...

avatar richard67
richard67 - comment - 29 Jun 2022

For testing I've just installed OSMap Free via the Install From Web on a clean, new install of current 4.2-dev. I get an error alert shown, but despite or debug and error reporting no stack trace and nothing in the error log. The error alert says:

2416: /home/richard/lamp/public_html/joomla-cms-4.2-dev/libraries/src/Installer/Installer.php
Installer::getDatabase() - Database not set in Joomla\CMS\Installer\Installer

I think that's nothing new now, but I thought I leave that info about another way to reproduce the issue.

avatar Fedik
Fedik - comment - 29 Jun 2022

The bug happened because DB injected in Installer::getInstance()

public static function getInstance($basepath = __DIR__, $classprefix = '\\Joomla\\CMS\\Installer\\Adapter', $adapterfolder = 'Adapter')
{
if (!isset(self::$instances[$basepath])) {
self::$instances[$basepath] = new static($basepath, $classprefix, $adapterfolder);
self::$instances[$basepath]->setDatabase(Factory::getContainer()->get(DatabaseInterface::class));
}

And not in constructor,
then Installer::getInstance() will work and new Installer will fail.

Not sure what correct fix.

avatar Fedik Fedik - change - 29 Jun 2022
Labels Added: Release Blocker
avatar Fedik Fedik - labeled - 29 Jun 2022
avatar Fedik
Fedik - comment - 29 Jun 2022

Addittionaly, developers can extend our Installer class, and override getInstance or __construct.
That makes things a bit more complicated.

avatar laoneo
laoneo - comment - 30 Jun 2022

Please test #38187.

avatar richard67 richard67 - change - 30 Jun 2022
Status New Closed
Closed_Date 0000-00-00 00:00:00 2022-06-30 08:13:00
Closed_By richard67
avatar richard67 richard67 - close - 30 Jun 2022
avatar richard67
richard67 - comment - 30 Jun 2022

Closing as having a pull request.

avatar richard67 richard67 - change - 30 Jun 2022
Labels Removed: Release Blocker
avatar richard67 richard67 - unlabeled - 30 Jun 2022

Add a Comment

Login with GitHub to post a comment