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

[REGRESSION] - quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true broken in 3.18 #45992

Closed
edeandrea opened this issue Jan 30, 2025 · 14 comments · Fixed by #46002
Labels
area/jackson Issues related to Jackson (JSON library) kind/bug Something isn't working triage/regression
Milestone

Comments

@edeandrea
Copy link
Contributor

edeandrea commented Jan 30, 2025

Describe the bug

I've found that setting quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true on 3.18 causes some things to break

How to Reproduce?

rest-fights.zip

  1. Unzip
  2. cd rest-fights
  3. ./mvnw clean verify

There are two unit tests - 1 should pass and one should fail. If you change the quarkus version back to 3.17.8 all the tests pass.

@edeandrea edeandrea added the kind/bug Something isn't working label Jan 30, 2025
Copy link

quarkus-bot bot commented Jan 30, 2025

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

@quarkus-bot quarkus-bot bot added the area/jackson Issues related to Jackson (JSON library) label Jan 30, 2025
@geoand
Copy link
Contributor

geoand commented Jan 31, 2025

I'll look into this as it's really weird

@geoand
Copy link
Contributor

geoand commented Jan 31, 2025

Actually, the status code is a result of how the test is setup and a bug in the generated deserializers. Fixing the deserializers will automatically fix the issue.

Here is what the deserializer for FightLocation looks like:

public class FightLocation$quarkusjacksondeserializer extends StdDeserializer {
   public FightLocation$quarkusjacksondeserializer() {
      super(FightLocation.class);
   }

   public Object deserialize(JsonParser var1, DeserializationContext var2) throws IOException, JacksonException {
      JsonNode var3 = (JsonNode)var1.getCodec().readTree(var1);
      FightLocation var9 = new FightLocation();
      Iterator var4 = var3.fields();

      while (var4.hasNext()) {
         Entry var5 = (Entry)var4.next();
         JsonNode var8 = (JsonNode)var5.getValue();
         if (!var8.isNull()) {
            Object var6 = var5.getKey();
            int var7 = var6.hashCode();
            switch (var7) {
               case -1724546052:
                  if ("description".equals(var6)) {
                     var8.asText();
                  }
                  break;
               case -577741570:
                  if ("picture".equals(var6)) {
                     var8.asText();
                  }
                  break;
               case 3373707:
                  if ("name".equals(var6)) {
                     var8.asText();
                  }
            }
         }
      }

      return var9;
   }
}

The switch looks very weird, so at this point I'll turn it over to @mariofusco.

@mariofusco
Copy link
Contributor

@geoand That's weird, I don't think that I have changed that code recently, but I will give a look immediately.

@geoand
Copy link
Contributor

geoand commented Jan 31, 2025

Maybe it's a bug in gizmo? cc @Ladicek

@Ladicek
Copy link
Contributor

Ladicek commented Jan 31, 2025

The last Gizmo release has happened a year ago, so if there's a difference between Quarkus 3.17 and 3.18, I'm fairly sure it's not Gizmo's fault.

@Ladicek
Copy link
Contributor

Ladicek commented Jan 31, 2025

That switch statement in one of the previous comments is basically a switch on Strings, there's nothing wrong with it.

EDIT: actually, there is. The obtained values are not assigned anywhere.

@geoand
Copy link
Contributor

geoand commented Jan 31, 2025

The last Gizmo release has happened a year ago, so if there's a difference between Quarkus 3.17 and 3.18, I'm fairly sure it's not Gizmo's fault.

Gotcha, thanks

@geoand
Copy link
Contributor

geoand commented Jan 31, 2025

With Quarkus 3.17.8, the deserializer looks like this:

public class FightRequest$quarkusjacksondeserializer extends StdDeserializer {
   public FightRequest$quarkusjacksondeserializer() {
      super(FightRequest.class);
   }
}

@mariofusco
Copy link
Contributor

With Quarkus 3.17.8, the deserializer looks like this:

public class FightRequest$quarkusjacksondeserializer extends StdDeserializer {
public FightRequest$quarkusjacksondeserializer() {
super(FightRequest.class);
}
}

In Quarkus 3.17.8 that deserializer is generated and then discarded (not used) because it doesn't work with records. I made a change ee668b2 to overcome that limitation, but I didn't think to a situation of a record with an empty constructor like

public record FightLocation(String name, String description, String picture) {
  public FightLocation() {
    this(null, null, null);
  }
}

(@edeandrea why are you doing this? just joking 😄 ) so that the deserializer try to use that empty contructor but then it is not able to set any value on the immutable record, thus generating that useless switch. I will work on a fix.

@Ladicek
Copy link
Contributor

Ladicek commented Jan 31, 2025

For the record, in Jandex, you can find the canonical record constructor using ClassInfo.canonicalRecordConstructor().

@mariofusco
Copy link
Contributor

For the record, in Jandex, you can find the canonical record constructor using ClassInfo.canonicalRecordConstructor().

Nice, that's super helpful, thank you.

@mariofusco
Copy link
Contributor

This should fix the problem #46002

Thank you @Ladicek for your suggestion.

@quarkus-bot quarkus-bot bot added this to the 3.19 - main milestone Jan 31, 2025
@edeandrea
Copy link
Contributor Author

(@edeandrea why are you doing this? just joking 😄 )

Sorry @mariofusco I must be using it wrong. Always user error :)

But seriously, thank you all for getting this fixed so fast.

@gsmet gsmet modified the milestones: 3.19 - main, 3.18.2 Feb 4, 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 triage/regression
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants