8000 Upgrade to 5.4 failed: Invalid service the class is not set. · Issue #44342 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Upgrade to 5.4 failed: Invalid service the class is not set. #44342

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

Closed
gjuric opened this issue Nov 29, 2021 · 10 comments
Closed

Upgrade to 5.4 failed: Invalid service the class is not set. #44342

gjuric opened this issue Nov 29, 2021 · 10 comments

Comments

@gjuric
Copy link
Contributor
gjuric commented Nov 29, 2021

Symfony version(s) affected

5.4.0

Description

I've just tried updating from latest 5.3.11 to 5.4.0 and after the packages have been updated the container can not be built with complaints about my custom repositories not having a class set.

How to reproduce

I've created a reproducer here: https://github.com/gjuric/symfony_5_4_bug/

The repositories are defined like this:

    <service id="Namespace\MyCustomDoctrineRepository">
        <factory service="doctrine.orm.default_entity_manager" method="getRepository"/>
        <argument>FQCN_of_my_entity</argument>
    </service>

I've tried adding the class attribute to the <service> tag but it doesn't help.

Possible Solution

No response

Additional Context

When compiler is trying to build this server it sees it has a factory and tries to fetch the Class here:

$class = $this->container->findDefinition((string) $class)->getClass();

$this->container->findDefinition((string) $class) returns and instance of Symfony\Component\DependencyInjection\ChildDefinition where parent is set to doctrine.orm.entity_manager.abstract and the class property is set to null. This null is then passed to return $this->getReflectionMethod(new Definition($class), $method); where it is of course not possible to build a definition since $class is null.

@wouterj
Copy link
Member
wouterj commented Nov 29, 2021

Hi @gjuric!

Can you provide a minimal reproducer that shows this error? That'll help someone (or you 😉) to debug this error.

@gjuric
Copy link
Contributor Author
gjuric commented Nov 29, 2021

Sure, I will take a look at it tomorrow, I've tried setting up the skeleton app from the linked documentation but it installs v6, after manually downgrading to 5.4 I wasn't able to install the maker bundle because of dependencies and downgrading to 5.3 to get the maker bundle broke the skeleton app because of a missing method in the MicroKernelTrait so I need to take care of that first :)

@signor-pedro
Copy link
Contributor
signor-pedro commented Nov 30, 2021

Hi, at our company we're experiencing the same :) thanks @gjuric for the minimal reproducer :)

@gjuric
Copy link
Contributor Author
gjuric commented Nov 30, 2021

I am having trouble generating a minimal reproducer since there using a factory to get the Entity Repository works :(

If I downgrade the symfony/framework-bundle package to v5.3.11 and leave all other packages upgraded everything works. The debug output when running bin/console is:


  [Symfony\Component\DependencyInjection\Exception\RuntimeException]
  Invalid service "Namespace\DoctrineOrmMyEntityRepository": the class is not set.


Exception trace:
  at vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:178
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->getReflectionMethod() at vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:143
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->getConstructor() at vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php:102
 Symfony\Component\DependencyInjection\Compiler\AttributeAutoconfigurationPass->processValue() at vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:81
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->processValue() at vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php:88
 Symfony\Component\DependencyInjection\Compiler\AttributeAutoconfigurationPass->processValue() at vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php:46
 Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass->process() at vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php:77
 Symfony\Component\DependencyInjection\Compiler\AttributeAutoconfigurationPass->process() at vendor/symfony/dependency-injection/Compiler/Compiler.php:82
 Symfony\Component\DependencyInjection\Compiler\Compiler->compile() at vendor/symfony/dependency-injection/ContainerBuilder.php:757
 Symfony\Component\DependencyInjection\ContainerBuilder->compile() at vendor/symfony/http-kernel/Kernel.php:548
 Symfony\Component\HttpKernel\Kernel->initializeContainer() at vendor/symfony/http-kernel/Kernel.php:789
 Symfony\Component\HttpKernel\Kernel->preBoot() at vendor/symfony/http-kernel/Kernel.php:128
 Symfony\Component\HttpKernel\Kernel->boot() at vendor/symfony/framework-bundle/Console/Application.php:168
 Symfony\Bundle\FrameworkBundle\Console\Application->registerCommands() at vendor/symfony/framework-bundle/Console/Application.php:74
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at vendor/symfony/console/Application.php:171
 Symfony\Component\Console\Application->run() at vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:54
 Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at vendor/autoload_runtime.php:35
 require_once() at bin/console:10

Couple of things to add:

  • we are using multiple entity managers
  • bundles that define these repositories add a DoctrineOrmMappingsPass::createXmlMappingDriver() compiler Pass to the container so entites from the bundle are registered with Doctrine

@gjuric
Copy link
Contributor Author
gjuric commented Nov 30, 2021

I've managed to create a reproducer and I've updated the issue with additional context.

@wouterj
Copy link
Member
wouterj commented Nov 30, 2021

Thanks a lot @gjuric!

The lines you mention in the PR description haven't been changed for years. However, if I use Symfony 5.3 I get $class = 'Doctrine\ORM\EntityManager';, whereas it's null in Symfony 5.4.

Would be cool if someone can dig deeper into this :)

@fancyweb
Copy link
Contributor

Looks like a bug on 4.4 here

. $class can be null, even with $required = false, getConstructor() ends up throwing.

getConstructor() is called here

if ($this->parameterAttributeConfigurators && $constructorReflector = $this->getConstructor($value, false)) {
.

I guess if there is no class in the definition with $required = false, getConstructor() should return null.

@fancyweb fancyweb self-assigned this Nov 30, 2021
@fancyweb
Copy link
Contributor
fancyweb commented Dec 1, 2021

Actually, let's catch the exception, that's what we do everywhere else, I'll submit a patch.

nicolas-grekas added a commit that referenced this issue Dec 1, 2021
…rs in AttributeAutoconfigurationPass if we can't get the constructor reflector (fancyweb)

This PR was merged into the 5.4 branch.

Discussion
----------

[DependencyInjection] Skip parameter attribute configurators in AttributeAutoconfigurationPass if we can't get the constructor reflector

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #44342
| License       | MIT
| Doc PR        | -

`$required = false` on `getConstructor()` doesn't mean it doesn't throw. I have looked at our other usages, and we catch the exception when we want to ignore it. I'd still like to return null when the definition class is null though (on 4.4).

Commits
-------

b2fe0e0 [DependencyInjection] Skip parameter attribute configurators in AttributeA
8000
utoconfigurationPass if we can't get the constructor reflector
@gjuric
Copy link
Contributor Author
gjuric commented Dec 6, 2021

@nicolas-grekas @fancyweb any chance of 5.4.1 being released with this fix in it?

@xabbuh
Copy link
Member
xabbuh commented Dec 6, 2021

Patch releases are usually done regularly once a month.

nicolas-grekas added a commit that referenced this issue Dec 11, 2021
…ecursivePass (fancyweb)

This PR was merged into the 4.4 branch.

Discussion
----------

[DependencyInjection] Resolve ChildDefinition in AbstractRecursivePass

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #44342
| License       | MIT
| Doc PR        | -

At least `AttributeAutoconfigurationPass` (5.4 new pass) relies on `AbstractRecursivePass` and is executed before `ResolveChildDefinitionsPass` so child definitions are not necessary resolved in `AbstractRecursivePass`. Doing it on 4.4 to have the same behavior on all maintained branches.

It fixes #44342 in a better way because the final class of the factory can be resolved.

Commits
-------

acbee81 [DependencyInjection] Resolve ChildDefinition in AbstractRecursivePass
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

7 participants
0