Cannot generate lazy proxy: class "Zenstruck\Messenger\Test\Bus\TestBus" is final
When running tests or building the container in the test environment after update to 7.3.4, Symfony fails to generate a lazy proxy for the messenger bus argument and throws:
In ProxyHelper.php line 139: Cannot generate lazy proxy: class "Zenstruck\Messenger\Test\Bus\TestBus" is final.
I attempted to work around the issue by modifying services.yaml, but I was unsuccessful. I use multiple buses in the system.
buses:
command.bus:
middleware:
- doctrine_ping_connection
query.bus:
middleware:
- validation
hi @FabienWebavenir
strange that this is not reproduced by our testsuite 🤔
I just run it with sf 7.3.4 + php 8.3
Details
➜ composer info symfony/*
symfony/browser-kit 7.3.2 Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically
symfony/cache 7.3.5 Provides extended PSR-6, PSR-16 (and tags) implementations
symfony/cache-contracts 3.6.0 Generic abstractions related to caching
symfony/clock 7.3.0 Decouples applications from the system clock
symfony/config 7.3.4 Helps you find, load, combine, autofill and validate configuration values of any kind
symfony/dependency-injection 7.3.4 Allows you to standardize and centralize the way objects are constructed in your application
symfony/deprecation-contracts 3.6.0 A generic function and convention to trigger deprecation notices
symfony/dom-crawler 7.3.3 Eases DOM navigation for HTML and XML documents
symfony/error-handler 7.3.4 Provides tools to manage errors and ease debugging PHP code
symfony/event-dispatcher 7.3.3 Provides tools that allow your application components to communicate with each other by dispatching events and listening to them
symfony/event-dispatcher-contracts 3.6.0 Generic abstractions related to dispatching event
symfony/filesystem 7.3.2 Provides basic utilities for the filesystem
symfony/finder 7.3.5 Finds files and directories via an intuitive fluent interface
symfony/framework-bundle 7.3.5 Provides a tight integration between Symfony components and the Symfony full-stack framework
symfony/http-foundation 7.3.5 Defines an object-oriented layer for the HTTP specification
symfony/http-kernel 7.3.5 Provides a structured process for converting a Request into a Response
symfony/messenger 7.3.3 Helps applications send and receive messages to/from other applications or via message queues
symfony/phpunit-bridge 7.3.4 Provides utilities for PHPUnit, especially user deprecation notices management
symfony/polyfill-ctype 1.33.0 Symfony polyfill for ctype functions
symfony/polyfill-mbstring 1.33.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php81 1.33.0 Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions
symfony/polyfill-php83 1.33.0 Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions
symfony/routing 7.3.4 Maps an HTTP request to a set of configuration variables
symfony/service-contracts 3.6.0 Generic abstractions related to writing services
symfony/var-dumper 7.3.5 Provides mechanisms for walking through any arbitrary PHP variable
symfony/var-exporter 7.3.4 Allows exporting any serializable PHP data structure to plain PHP code
symfony/yaml 7.3.5 Loads and dumps YAML files
➜ vendor/bin/simple-phpunit
PHPUnit 9.6.29 by Sebastian Bergmann and contributors.
Testing ................................................................. 65 / 74 ( 87%) ......... 74 / 74 (100%)
Time: 00:00.912, Memory: 34.00 MB
OK (74 tests, 402 assertions)
I think the fix is straightforward: replace the final keyword on the TestBus by a @final PHPDoc.
Any chance you create a reproducer? I'd like to know in which case this could occur
Hi @nikophil
Thank for you response.
While trying to reproduce the issue on a new project, I identified the source of the error. In my project, I have a CommandBus service with the following constructor:
class CommandBus
{
use HandleTrait;
public function __construct(
#[Lazy] #[Target('command.bus')]
private MessageBusInterface $messageBus,
) {
}
/**
* @return mixed The handler returned value
*/
public function command(CommandInterface $command): mixed
{
return $this->handle($command);
}
public function getMessageBus(): MessageBusInterface
{
return $this->messageBus;
}
}
Setting it to #[Lazy] causes this error during testing because it injects TestBus, which is final.
cool, thanks for the answer!
Actually in my previous answer, I was about to ask if you were using a #[Lazy] attribute 😅
But this is weird, because you're injecting an interface, it should not create this kind of problem 🤔
which PHP version are you using? Could also find which Symfony version is the culprit and which package? (framework bundle, symfony/di or symfony/var-exporter?)
thanks!
I’ve created a repository to reproduce the issue. There’s no real logic in it, but it allows testing: https://github.com/FabienWebavenir/zenstruck-messenger-test
When running the tests, I do get the error. The file with the Lazy attribute is App\Core\MessageBus\CommandBus.
make build
make up
make test