eclipse-ee4j / yasson

Eclipse Yasson project
https://projects.eclipse.org/projects/ee4j.yasson
Other
204 stars 96 forks source link

Yasson ignores @JsonbTypeAdapter on class level of object in Collection #652

Open mkarg opened 1 month ago

mkarg commented 1 month ago

Describe the bug

According to the JSON-B Specification v3 chapter 4.7.1...

There are two ways how to register JsonbAdapter:

  • Using JsonbConfig::withAdapters method;
  • Annotating a class field with JsonbTypeAdapter annotation.

Yasson 3.0.4 inconsistently handles adapters for objects in collections:

To Reproduce

public class YassonBug {

  public static void main(String[] arguments) throws Exception {
    var c = new C();

    // Correctly applies @JsonbTypeAdapter in both cases
    try (var jsonb = JsonbBuilder.newBuilder().build()) {
      System.out.println(jsonb.toJson(c)); // correctly prints `"correct value"`
      System.out.println(jsonb.toJson(Set.of(c))); // correctly prints `["correct value"]`
    }

    // Correctly applies config in both cases
    var config = new JsonbConfig().withAdapters(new CAdapter());
    try (var jsonb = JsonbBuilder.newBuilder().withConfig(config).build()) {
      System.out.println(jsonb.toJson(Set.of(c))); // correctly prints `["correct value"]`
      System.out.println(jsonb.toJson(c)); // correctly prints `"correct value"`
    }

    // Incorrectly applies @JsonbTypeAdapter in the `List.of(c)` case (and remembers wrong decision in the `c` case)
    try (var jsonb = JsonbBuilder.newBuilder().build()) {
      System.out.println(jsonb.toJson(Set.of(c))); // incorrectly prints `[{"wrong":"value"}]`, should be `["correct value"]`
      System.out.println(jsonb.toJson(c)); // incorrectly prints `{"wrong":"value"}`, should be `"correct value"`
    }
  }

  @JsonbTypeAdapter(CAdapter.class)
  public static class C {
    public String wrong = "value"; 
  }

  public static class CAdapter implements JsonbAdapter<C, String> {

    @Override
    public String adaptToJson(C obj) throws Exception {
      return "correct value";
    }

    @Override
    public C adaptFromJson(String obj) throws Exception {
      throw new UnsupportedOperationException("Unimplemented method 'adaptFromJson'");
    }

  }

}

Expected behavior

Yasson should correctly respect adapter for object in collection registered using @JsonbTypeAdapter just in the same ways it already correctly respects adapters set using ::withAdapters.

System information:

Additional context

See also https://github.com/eclipse-ee4j/yasson/issues/603.