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

Reflection-free Serialization issue when first accessed vs. second access or if multiple methods #46156

Closed
kjq opened this issue Feb 8, 2025 · 8 comments · Fixed by #46211
Closed
Labels
area/jackson Issues related to Jackson (JSON library) kind/bug Something isn't working
Milestone

Comments

@kjq
Copy link

kjq commented Feb 8, 2025

Describe the bug

The weirdest issue and I do not understand why.

When reflection-free serialization is on I have a case where the object is not properly serialized the first time but if I reload the dev server it works the second time. In production it just did not work.

In our real code we can verify these issues:

  1. The 1st time we hit the endpoint the object is not correct / Reloading quarkus:dev then hitting the same endpoint the object is there
  2. If I instead move all the properties into the main object and do not extend it works fine.
  3. If I muck around with the JSON properties, remove @JsonIgnore and make them all @JsonProperty it seems to work fine.

I was finally able to replicated it after I compared the bytecode and then added the "list" endpoint so that it matched our scenario.

Expected behavior

Serialization works the same when reflection-free is enabled for simple POJOs

Actual behavior

Various issues but the children object happens to be missing in this case.

Reloading quarkus:dev and hitting the same URL works the 2nd time.

How to Reproduce?

Scenario 1:

  1. mvn clean install
  2. In the "rest" project run mvn quarkus:dev
  3. Navigate to http://localhost:8080/hello - no child objects
  4. Reload quarkus:dev (press S)
  5. Navigate to http://localhost:8080/hello - child object is there

Scenario 2:

  1. Comment out the "list" endpoint
  2. In the "rest" project run mvn quarkus:dev
  3. Navigate to http://localhost:8080/hello - child object is there

code-with-quarkus.zip

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

3.18.2

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

Maven

Additional information

No response

@kjq kjq added the kind/bug Something isn't working label Feb 8, 2025
@kjq kjq changed the title Reflection-free Serialization Issue when a List and Object method present Reflection-free Serialization issue when first accessed vs. second access and if other methods included Feb 8, 2025
@kjq kjq changed the title Reflection-free Serialization issue when first accessed vs. second access and if other methods included Reflection-free Serialization issue when first accessed vs. second access or if multiple methods Feb 8, 2025
@gsmet
Copy link
Member

gsmet commented Feb 8, 2025

@mariofusco looks like a good puzzle for you :)

@kjq
Copy link
Author

kjq commented Feb 9, 2025

I wanted to double-check my work so you didn't think I was a fool with this issue (and to make sure I was not losing my mind).

Originally, for the life of me I could not replicate this and I literally copied almost the exact code over. It wasn't until I generated the decompiled output and compared those and saw the only difference was the list endpoint was missing (not that this is the root cause of the issue just the only thing different). Once I added that I get the same results.

In all cases, up to the point it is returned in the response, the "model" has the correct values and if i set enable-reflection-free-serializers: false it works always as expected.

So, the issues I have are:

  • JSON response is odd depending on the 1st vs. 2nd+ times accessing it
  • quarkus.jackson properties seem to be ignored

Scenario 1:

  1. mvn install the project
  2. cd rest
  3. mvn quarkus:dev
  4. Navigate to http://localhost:8080/scenario1 - no ReferenceRepository in JSON response
  5. Reload quarkus:dev (press S)
  6. Navigate to http://localhost:8080/scenario1 - hasReferenceRepository in JSON response
  7. Exit quarkus:dev

Once it shows up in the response (after step# 5) it always does.

Note, here it seems to also ignore the quarkus.jackson properties until reloaded (i.e. exclude non_default values)

Scenario 2:

  1. mvn install the project
  2. cd rest
  3. mvn quarkus:dev
  4. Navigate to http://localhost:8080/scenario2 - hasReferenceRepository in JSON response
  5. Exit quarkus:dev

This is the same as scenario1 except rather than "extending" the base I have the all fields inside the model.

Note, here it respects the quarkus.jackson properties which somewhat implies my ordinal loading is correct (likewise, if reflection free is disabled it also respects the jackson properties).

Scenario 3:

  1. Comment out the whole /list endpoint entirely.
  2. mvn install
  3. mvn quarkus:dev
  4. Navigate to http://localhost:8080/scenario1 - has ReferenceRepository in JSON response

Other things I tried but had no effect:

  • I tried creating another resource without the list endpoint to see if it was specific to the resource class itself
  • Removed Lombok and just used getters/setters to make sure processor was not the issue
  • Bringing in every extension we use to see if something was conflicting
  • Running the JAR locally to see if it was a difference btw quarkus:dev and not
  • Renaming my getters/setters for JSON serialization better to make sure there was no weirdness in the set(Map) vs. get::List.

When running under quarkus:dev I can reproduce the issue, reload or finagle it, and get it to work. When deployed, JVM or native, it just does not work (assuming it has to do with that 1st vs. 2nd load). I always have to exist quarkus:dev though or i get a false positive that it works.

Now, here is where it gets more interesting. I have other services with the exact same pattern just different models. Those work (tests verify these and I performed the same steps above in dev and staging environments).

I beefed up my reproducer and cleaned it up to remove what was not needed:

code-with-quarkus.zip

@kjq
Copy link
Author

kjq commented Feb 9, 2025

It has nothing to do with the config_ordinal (i accidentally had reflection-free disabled).

@kjq
Copy link
Author

kjq commented Feb 9, 2025

I deleted my code-with-quarkus2.zip because I thought that was irrelavant but it still holds true - if you replace @JsonIgnore with @JsonProperty and run scenario1 it will work the first time but totally ignores the quarkus.jackson properties.

@mariofusco
Copy link
Contributor

@mariofusco looks like a good puzzle for you :)

I will check this asap, but this week I'm traveling so it won't be immediate.

@geoand geoand added area/jackson Issues related to Jackson (JSON library) and removed triage/needs-triage labels Feb 10, 2025
@mariofusco
Copy link
Contributor

I have an isolated reproducer and know why this is happening. I need a bit of time to implement a solution, something related to what I discussed here FasterXML/jackson-databind#1784

@kjq
Copy link
Author

kjq commented Feb 10, 2025

No worries on our end, we have two acceptable solutions that work (unless you think otherwise). Thank you for looking into this. I wish I could of been more help but now I am more interested in the why (which I sort of followed from that thread).

@mariofusco
Copy link
Contributor

Fixed by #46211

@quarkus-bot quarkus-bot bot added this to the 3.19 - main milestone Feb 11, 2025
@gsmet gsmet modified the milestones: 3.19 - main, 3.18.3 Feb 11, 2025
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/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants