{"action":"created","issue":{"url":"https://api.github.com/repos/symfony/symfony/issues/29019","repository_url":"https://api.github.com/repos/symfony/symfony","labels_url":"https://api.github.com/repos/symfony/symfony/issues/29019/labels{/name}","comments_url":"https://api.github.com/repos/symfony/symfony/issues/29019/comments","events_url":"https://api.github.com/repos/symfony/symfony/issues/29019/events","html_url":"https://github.com/symfony/symfony/issues/29019","id":375136757,"node_id":"MDU6SXNzdWUzNzUxMzY3NTc=","number":29019,"title":"ContainerBuilder::getReflectionClass() + autowiring breaks resource cache & debug:config","user":{"login":"weaverryan","id":121003,"node_id":"MDQ6VXNlcjEyMTAwMw==","avatar_url":"https://avatars1.githubusercontent.com/u/121003?v=4","gravatar_id":"","url":"https://api.github.com/users/weaverryan","html_url":"https://github.com/weaverryan","followers_url":"https://api.github.com/users/weaverryan/followers","following_url":"https://api.github.com/users/weaverryan/following{/other_user}","gists_url":"https://api.github.com/users/weaverryan/gists{/gist_id}","starred_url":"https://api.github.com/users/weaverryan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weaverryan/subscriptions","organizations_url":"https://api.github.com/users/weaverryan/orgs","repos_url":"https://api.github.com/users/weaverryan/repos","events_url":"https://api.github.com/users/weaverryan/events{/privacy}","received_events_url":"https://api.github.com/users/weaverryan/received_events","type":"User","site_admin":false},"labels":[{"id":100079,"node_id":"MDU6TGFiZWwxMDAwNzk=","url":"https://api.github.com/repos/symfony/symfony/labels/Bug","name":"Bug","color":"e10c02","default":false},{"id":99863,"node_id":"MDU6TGFiZWw5OTg2Mw==","url":"https://api.github.com/repos/symfony/symfony/labels/DependencyInjection","name":"DependencyInjection","color":"DDDDDD","default":false},{"id":237003792,"node_id":"MDU6TGFiZWwyMzcwMDM3OTI=","url":"https://api.github.com/repos/symfony/symfony/labels/Status:%20Needs%20Review","name":"Status: Needs Review","color":"ededed","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-10-29T17:40:54Z","updated_at":"2018-11-06T15:54:29Z","closed_at":"2018-11-06T15:54:29Z","author_association":"MEMBER","body":"**Symfony version(s) affected**: 4.1.6 (but probably back to 3.4)\r\n\r\n**Description**  \r\nHey guys!\r\n\r\nI found a very deep bug related to autowiring & the container resources. Steps to reproduce are below, but here is a description of the issue. Also, this seems to only affect the `debug:config` and related commands where the container is rebuilt manually. The normal container does not seem to suffer from this problem. The key part is 3 - I believe that's where the bug actually exists.\r\n\r\n1) In `AutowirePass`, a type somewhere in the system cannot be guessed. And so, `AutowirePass:: populateAvailableTypes()` is called to try to determine a good error message. This is already slightly flawed, as the error message may ultimately be \"hidden\" because the definition in question is removed... and so we're doing work unnecessarily. But, that's not the bug - just a little performance thing.\r\n\r\n2) The `AutowirePass::populateAvailableTypes()` eventually calls: `$this->container->getReflectionClass($definition->getClass(), false)` on each definition.\r\n\r\n3) Here is the important part: IF the class in question exists (e.g. `DoctrineOrmTypeGuesser` was the culprit for me) but some of the interfaces that it implements do NOT exist, then the `ContainerBuilder::getReflectionClass()` method will create and use a `ClassExistenceResource` for that class where `$exists = false`.\r\n\r\n4) The next time the container checks to see if its cache is fresh, it will always return false because the class above (e.g. `DoctrineOrmTypeGuesser`) DOES exist, but its `ClassExistenceResource` expects it to not exist.\r\n\r\n**How to reproduce**  \r\nReproducer: https://github.com/weaverryan/autowiring-class-existence-reproducer\r\n\r\nSteps:\r\n1) Install `form` (because it has a good example - `DoctrineOrmTypeGuesser`) of a class that will be registered as a service, even though some of its parent interfaces do not exist in the app\r\n\r\n2) Create an \"autowiring failure\" situation that will ultimately be silent. Easy way: add a controller and type-hint it with an entity.\r\n\r\n3) Install `security`. Not needed for the bug - it's just an easy way to \"see\" the bug... because the bad behavior causes a weird situation.\r\n\r\n4) Run `rm -rf var/cache/* && php bin/console debug:config framework`. You'll see this exception:\r\n\r\n> The service \"debug.security.firewall\" has a dependency on a non-existent service \".security.  \r\n request_matcher.zfHj2lW\".\r\n\r\nThis is not really the bug - it's just a \"symptom\" of the fact that `debug:config` will build the container multiple times, because after building it, it immediately looks \"stale\".\r\n\r\n**Possible Solution**  \r\nMake `ContainerBuilder::getReflectionClass()` a bit smarter: only add the class existence resource if the class really does *not* exist?\r\n"},"comment":{"url":"https://api.github.com/repos/symfony/symfony/issues/comments/436303244","html_url":"https://github.com/symfony/symfony/issues/29019#issuecomment-436303244","issue_url":"https://api.github.com/repos/symfony/symfony/issues/29019","id":436303244,"node_id":"MDEyOklzc3VlQ29tbWVudDQzNjMwMzI0NA==","user":{"login":"nicolas-grekas","id":243674,"node_id":"MDQ6VXNlcjI0MzY3NA==","avatar_url":"https://avatars3.githubusercontent.com/u/243674?v=4","gravatar_id":"","url":"https://api.github.com/users/nicolas-grekas","html_url":"https://github.com/nicolas-grekas","followers_url":"https://api.github.com/users/nicolas-grekas/followers","following_url":"https://api.github.com/users/nicolas-grekas/following{/other_user}","gists_url":"https://api.github.com/users/nicolas-grekas/gists{/gist_id}","starred_url":"https://api.github.com/users/nicolas-grekas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nicolas-grekas/subscriptions","organizations_url":"https://api.github.com/users/nicolas-grekas/orgs","repos_url":"https://api.github.com/users/nicolas-grekas/repos","events_url":"https://api.github.com/users/nicolas-grekas/events{/privacy}","received_events_url":"https://api.github.com/users/nicolas-grekas/received_events","type":"User","site_admin":false},"created_at":"2018-11-06T15:54:29Z","updated_at":"2018-11-06T15:54:29Z","author_association":"MEMBER","body":"Cheers :)"}}
{"actor":{"display_login":"nicolas-grekas"}}