Skip to content
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

Symfony 6.4 has a dependency on a non-existent service "annotation_reader" #943

Closed
99hops opened this issue Nov 30, 2023 · 6 comments
Closed

Comments

@99hops
Copy link

99hops commented Nov 30, 2023

Hello, on fresh SF 6.4 setup after adding JMS I get

The service "jms_serializer.metadata.annotation_and_attributes_reader" has a dependency on a non-existent service "annotation_reader".

Which comes from

framework:
    annotations: false

What is the solution to this?

I've checked configuration reference and don't see any relevant options to play with.

Thanks! (:

@99hops
Copy link
Author

99hops commented Dec 1, 2023

I looking at this and I see few things related

$metadataDrivers = [
            new Reference('jms_serializer.metadata.yaml_driver'),
            new Reference('jms_serializer.metadata.xml_driver'),
            // new Reference('jms_serializer.metadata.attribute_driver'), // TODO - Re-enable this driver at a later time
            new Reference('jms_serializer.metadata.annotation_driver'),
        ];

        // enable attributes support on php 8
        if (PHP_VERSION_ID >= 80000 && class_exists(AttributeReader::class)) {
            $container->register('jms_serializer.metadata.annotation_and_attributes_reader', AttributeReader::class)
                ->setArgument(0, new Reference('annotation_reader'));

            $container->findDefinition('jms_serializer.metadata.annotation_driver')
                ->replaceArgument(0, new Reference('jms_serializer.metadata.annotation_and_attributes_reader'));
        }

and

<service id="jms_serializer.metadata.annotation_driver" class="JMS\Serializer\Metadata\Driver\AnnotationDriver" public="false">
            <argument type="service" id="annotation_reader" />
            <argument type="service" id="jms_serializer.naming_strategy" />
            <argument type="service" id="jms_serializer.type_parser" on-invalid="null" />
            <argument type="constant">NULL</argument> <!-- expression evaluator -->
        </service>
        <!-- TODO - Re-enable this driver at a later time -->
        <!-- <service id="jms_serializer.metadata.attribute_driver" class="JMS\Serializer\Metadata\Driver\AttributeDriver" public="false">
            <argument type="service" id="jms_serializer.naming_strategy" />
            <argument type="service" id="jms_serializer.type_parser" on-invalid="null" />
            <argument type="constant">NULL</argument>
        </service> -->

Please advice @goetas @schmittjoh
Thanks!

@scyzoryck
Copy link
Collaborator

Hi!
I'm afraid current implementation requires AnnotationReader dependency. I think this dependency will be solved with: #933

Best, scyzoryck.

@99hops
Copy link
Author

99hops commented Dec 1, 2023

Yeah, I saw this one, it's been there for a long time, for now the workaround I have is to have a base controller that does

use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy;
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface;
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\Expression\ExpressionEvaluator;

private readonly SerializerInterface $serializer;

public function __construct()
{
    $this->serializer = SerializerBuilder::create()
        ->setPropertyNamingStrategy(
            new SerializedNameAnnotationStrategy(
                new IdenticalPropertyNamingStrategy()
            )
        )
        ->setExpressionEvaluator(
            new ExpressionEvaluator(new ExpressionLanguage())
        )
        ->build();
}

$groups[] = 'all';
$context = SerializationContext::create()->setGroups($groups)->setSerializeNull(true);

$this->serializer->serialize($data, 'json', $context);

and keeping bundle disabled, but we all know it's not the same

@mbabker
Copy link
Contributor

mbabker commented Dec 1, 2023

That JMS\Serializer\Metadata\Driver\AttributeDriver\AttributeReader class that's getting wired in to enable attributes support as well as the JMS\Serializer\Metadata\Driver\AnnotationDriver class both have hard requirements to provide an annotation reader. So with the current stable release of this bundle, it is indeed impossible to turn off the framework's annotation support without using compiler passes to remove those drivers.

As pointed out, #933 does fix this by no longer using the jms_serializer.metadata.annotation_driver service (which needs the JMS\Serializer\Metadata\Driver\AnnotationDriver class and has the hardcoded annotations dependency) but instead switches to a driver that supports both annotations and attributes, with the annotation support being optional, and then #937 takes a step to further validate that the bundle can work when the Annotations package is not installed since the framework no longer provides an annotation reader service in Symfony 7.

So, the fixes are there, they just haven't shipped yet. And I'm sure the test coverage for running both the main library and this bundle without annotations can be further improved on, but being a deep-rooted dependency, it does take some time to work through decoupling it in a way that isn't intrusive to downstream users.

@goetas
Copy link
Collaborator

goetas commented Dec 12, 2023

@mbabker i know that you have worked a lot of this recently, can this be considered as solved after the recent symfony 7 compatibility release #937 ?

@mbabker
Copy link
Contributor

mbabker commented Dec 12, 2023

Yes, the combo of #933 and #937 should fix this in full.

@goetas goetas closed this as completed Dec 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants