eclipse-ee4j / eclipse-ee4j/yasson
Map<K, V> produces JSON list instead of JSON map
- Dominant language
- Java
- Stars
- 218
- Forks
- 109
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 9
Description
**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:
* `Map` is correctly serialized as a JSON **map** where `String` is key and serialized `V` is value.
```java
System.out.println(jsonb.toJson(Map.of(k.toString(), v))); // correctly prints `{"k":}`
```
* `Map` is rather unexpectedly serialized as a JSON **list** holding one JSON map per entry *inside* that list, all having a key name of literally the word `key`, and a value of literally the word `value`.
```java
System.out.println(jsonb.toJson(Map.of(k, v))); // prints `[{"key":,"value":}]`, but should print `{: }`
```
**To Reproduce**
```java
package de.quipsy.sandbox.yassonbugs;
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 {
@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 `{: }`, i. e. a map with serialized `k` as key and serialized `v` as value, to be consistent with the behaviour of `Map`.
**System information:**
- OS: Windows
- Java Version: 19
- Yasson Version: 3.0.3
**Additional context**
N/A
Contributor guide
Research direction
Start with the YassonBugs.main reproduction and compare serialization of Map with Map using the supplied CAdapter. Trace the map serialization entry point to determine why non-String keys produce a list of key/value objects. Done means the generic map serializes as a JSON object with serialized keys and values, with regression coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100