Skip to content

Running container is being deleted when dependency is autowired implicitly in Symfony 3 #27053

Closed
@ostrolucky

Description

@ostrolucky
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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions