Description
Q | A |
---|---|
Bug report? | yes |
Feature request? | no |
BC Break report? | no |
RFC? | no |
Symfony version | 3.4 |
I have changed constructor dependency from Doctrine's ApplicationRepository (which has service ID same as FCQN) into dependency which has ID not matching FCQN, configured with legacy style, like:
panel.application.application_history:
class: AppBundle\Panel\Panels\Application\ApplicationHistory
arguments: [ '@manager.application', '@manager.user' ]
class HistoryWindowController extends Controller
{
private $applicationHistoryPanel;
public function __construct(ApplicationHistory $applicationHistoryPanel)
{
$this->applicationHistoryPanel = $applicationHistoryPanel;
}
public function __invoke(Application $application)
{
...
}
}
It works. BUT
After doing that, tests started to blow up with messages like:
Symfony\Component\Debug\Exception\FatalErrorException:
Compile Error: ContainerX6wnwgd\appTestDebugProjectContainer::load(): Failed opening required '/var/www/var/cache/test/ContainerX6wnwgd/getJmsJobQueue_Entity_ManyToAnyListenerService.php' (include_path='.:/usr/local/lib/php')
at var/cache/test/ContainerX6wnwgd/appTestDebugProjectContainer.php:2481
at ContainerX6wnwgd\appTestDebugProjectContainer->load('file' => '???', 'lazyLoad' => '???')
(vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:304)
at ContainerX6wnwgd\appTestDebugProjectContainer->get('id' => '???', 'invalidBehavior' => '???')
(vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php:58)
at Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent('eventName' => '???', 'eventArgs' => '???')
(vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php:117)
at Doctrine\ORM\Event\ListenersInvoker->invoke('metadata' => '???', 'eventName' => '???', 'entity' => '???', 'event' => '???', 'invoke' => '???')
(vendor/doctrine/orm/lib/Doctrine/ORM/Internal/HydrationCompleteHandler.php:99)
Test looks like this:
$client = static::createClient();
$oppManager = $container->get('manager.opportunity');
$this->assertSomething($client->request(...));
$this->assertSomething($client->request(...));
$this->assertSomething($client->request(...));
$oppManager->findOneBy([])->getId(); // here it blows up
What I found is that after each $client->request(), container is being replaced, so when it comes to executing $oppManager->findOneBy()
, old container folder does no longer exist, so classes which weren't loaded yet at that point, cannot.
I also tried to find out why is container being regenerated and what I found is that resource is marked as ClassExistenceResource for EntityManager5ae0c6b8bc55b_546a8d27f194334ee012bfe64f629947b07e4919\__CG__\Doctrine\ORM\EntityManager
. Such key has false
value in \Symfony\Component\Config\Resource\ClassExistenceResource#existsCache[1]
. Variable $exists is true and $this->exists is false. This results in false return.
This issue has been discovered in Symfony 3.4.4. I updated and is still present in Symfony 3.4.8.
Issue is resolved when I alias the service so FCQN matches ID:
AppBundle\Panel\Panels\Application\ApplicationHistory: '@panel.application.application_history'
Here are some other things which might help:
- Controller is in AppBundle, but test is in ApiBundle (and doesn't test that controller).
- AppBundle tests don't have this issue, only ApiBundle ones
I realize these autowiring fallbacks are deprecated, but it shouldn't blow up like this and will make it hard to migrate