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

Cannot customize Jackson serializer and deserializer for java.time.Instant #33775

Closed
oaklandcorp-jkaiser opened this issue Jun 1, 2023 · 8 comments
Labels
area/jackson Issues related to Jackson (JSON library) kind/question Further information is requested

Comments

@oaklandcorp-jkaiser
Copy link

Describe the bug

I am trying to create a custom Jackson serializer + deserializer for some java.time types in an existing Quarkus 2 API to help break up the migration to Quarkus 3 in smaller less risky deployments. I'm using the ObjectMapperCustomizer interface to add my custom serializer + deserializer however during testing I can never seem to get my implementations used. I've even tried maxing out the priority of the customizer in case it was completing with the priority of internal customizers.

Expected behavior

I'd expect that my custom serializer and deserializer should be preferred across the API when dealing with the Instant type.

Actual behavior

Another implementation of a serializer and deserializer is used instead.

How to Reproduce?

In general it just involves creating a ObjectMapperCustomizer that registers a SimpleModule with a custom StdSerializer<Instant> and StdDeserializer<Instant>. I've created a small reproducible repo here to help aid tracking this one down.

Output of uname -a or ver

Linux tester 5.19.0-43-generic #44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon May 22 13:39:36 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "17.0.6" 2023-01-17 LTS OpenJDK Runtime Environment Corretto-17.0.6.10.1 (build 17.0.6+10-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.6.10.1 (build 17.0.6+10-LTS, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.16.4.Final

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

Very odd but if I add this line after registering my module in JacksonCustomizer my serializer seems to get used. Adding calls like canDeserialize hasn't helped me hack the use of my deserilizer into play.

objectMapper.canSerialize(Instant.class);
@oaklandcorp-jkaiser oaklandcorp-jkaiser added the kind/bug Something isn't working label Jun 1, 2023
@quarkus-bot quarkus-bot bot added the area/jackson Issues related to Jackson (JSON library) label Jun 1, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Jun 1, 2023

/cc @geoand (jackson), @gsmet (jackson)

@geoand
Copy link
Contributor

geoand commented Jun 1, 2023

Does this issue still occur with Quarkus 3.1.0.Final?

@oaklandcorp-jkaiser
Copy link
Author

Does this issue still occur with Quarkus 3.1.0.Final?

After a quarkus update --stream=3.1 the test continues to fail in the same way.

@geoand
Copy link
Contributor

geoand commented Jun 1, 2023

Thanks for the update

@oaklandcorp-jkaiser
Copy link
Author

oaklandcorp-jkaiser commented Jun 1, 2023

Uh, I might have found the issue :)

I think the default comparison implementation for ObjectMapperCustomizer might be reversed. I set the priority to MINIMUM_PRIORITY and now the test case passes.

// Added to JacksonCustomizer
@Override
public int priority() {
    return MINIMUM_PRIORITY;
}

@geoand
Copy link
Contributor

geoand commented Jun 1, 2023

As mentioned in the Javadoc of priority:

    /**
     * Defines the priority that the customizers are applied.
     * A lower integer value means that the customizer will be applied after a customizer with a higher priority
     */

So as you found, in order for your serializers to be used, the customizer needs to be run after the run Quarkus has by default that registers the JavaTimeModule

@geoand geoand closed this as completed Jun 1, 2023
@geoand geoand added kind/question Further information is requested and removed kind/bug Something isn't working labels Jun 1, 2023
@oaklandcorp-jkaiser
Copy link
Author

As mentioned in the Javadoc of priority:

    /**
     * Defines the priority that the customizers are applied.
     * A lower integer value means that the customizer will be applied after a customizer with a higher priority
     */

So as you found, in order for your serializers to be used, the customizer needs to be run after the run Quarkus has by default that registers the JavaTimeModule

Ah, that explains it! The documentation around QUARKUS_CUSTOMIZER_PRIORITY kept catching my eye and not priority. It's reversed for how I intuited priority here (that customizer has a higher priority -> stronger chance of being chosen) but that's just me and you've got exact documentation to describe how it should work so it is all good. Glad to be able to fix this one. Thanks for the explanation @geoand!

@geoand
Copy link
Contributor

geoand commented Jun 1, 2023

🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/jackson Issues related to Jackson (JSON library) kind/question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants