Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace failure #39045

Closed
MarkRS-UK opened this issue Oct 23, 2022 · 1 comment
Closed

Namespace failure #39045

MarkRS-UK opened this issue Oct 23, 2022 · 1 comment

Comments

@MarkRS-UK
Copy link
Contributor

MarkRS-UK commented Oct 23, 2022

A loaded class is using the wrong version of (one of) its interface(s), which then causes program fatal error.
More specifically, I have included the Google API Client code in my component. This uses, and loads, the Monolog library.
The Google log client, as is standard, implements a LoggerInterface interface. Also as is standard it refers to the interface namespace simply as "Psr\Log\LoggerInterface".

use Psr\Log\LoggerInterface;
class Logger implements LoggerInterface, ResettableInterface { /* code */ }

At the point of trying to load the logger, I think there are two other instances of this same namespace loaded in my setup. One is (slightly) specific to my setup, being the AkeebaBackup instance, but the other is central to Joomla, the core version (at "libraries/vendor/psr/log/Psr/Log/LoggerInterface").
I'm not entirely sure of the process here because, tracing the code, it loads the Logger class with autoload and then seems to pass over the first interface, LoggerInterface, and shows trying to load the resettable interface. It manages this and then immediately goes to the fatal error code. It complains that the interface signature of the (emergency) method doesn't match the class implementation. The emergency method is declared as

public function emergency(string|\Stringable $message, array $context = []): void

which does match the instance supplied with the Google code. Both the other interface declarations in Joomla are older and are

public function emergency($message, array $context = []);

And thus the class load fails complaining

Compile Error: Declaration of Monolog\Logger::emergency(Stringable|string , array = []): void must be compatible with Psr\Log\LoggerInterface::emergency(, array = [])

Steps to reproduce the issue

  1. Install vendor supplied (composer delivered) code that uses current (ie later version than that in the J! core) Monolog code as its logger.
  2. Make a call to this vendor code this vendor code that generates a log call. This might be "make faulty call to the code", or perhaps, as in the case of the Google Developer API, any call that then logs information.

Expected result

Error message showing the fault.

Actual result

Error 500, internal server error, complaining of faulty implementation of LoggerInterface class.

System information (as much as possible)

I have installed "vendor supplied code" into my custom component. I expect there are other ways to do it.

Additional comments

I wondered if changing the order of interface list on the logger class declaration might make a difference, putting LoggerInterface second. It doesn't.
I don't understand enough about php to know what's going on here.

@MarkRS-UK
Copy link
Contributor Author

This is not the issue I thought it was. Definitely a problem, but neither a php nor Joomla issue.

Monolog (since that is the specific issue here) may be used in different packages but (usually) always with the same namespacing. Joomla's namespacing strategy avoids crashes but prevents the use of different versions.

Applying an extra step to change the problematic namespace(s), for example using php-scoper, overcomes the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants