eclipse-ee4j / yasson

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

Map<K, V> produces JSON list instead of JSON map #602

Open mkarg opened 1 year ago

mkarg commented 1 year ago

Describe the bug

According to JSON-B Specification v3 chapter 3.1.1 all implementations MUST support serialization of java.util.Map. While Yasson does serialize maps, it does it in an inconsistent way:

import java.io.IOException; import java.util.Map;

import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.adapter.JsonbAdapter;

public final class YassonBugs {

public static final void main(final String[] arguments) throws IOException { final var cfg = new JsonbConfig().withAdapters(new CAdapter()); final var jsonb = JsonbBuilder.newBuilder().withConfig(cfg).build(); final var k = new C(); final var v = new C(); System.out.println(jsonb.toJson(Map.of(k.toString(), v))); // correctly prints {"C":"C"}] System.out.println(jsonb.toJson(Map.of(k, v))); // prints [{"key":"C","value":"C"}], but should print {"C": "C"} }

public static final class C { @Override public final String toString() { return "C"; } }

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

@Override
public final String adaptToJson(final C obj) throws Exception {
  return obj.toString();
}

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

}

}



**Expected behavior**
`System.out.println(jsonb.toJson(Map.of(k, v)));` should print print `{<k>: <v>}`, i. e. a map with serialized `k` as key and serialized `v` as value, to be consistent with the behaviour of `Map<String, V>`.

**System information:**
 - OS: Windows
 - Java Version: 19
 - Yasson Version: 3.0.3

**Additional context**
N/A
Degubi commented 1 year ago

Not sure what the correct behaviour is in this case, but the serializer selection happens here in MapSerializer.java. According to this code only using Enum keys or the types defined in TypeSerializers.java are supported as keys.