eclipse-ee4j / eclipse-ee4j/yasson

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

Open
#602 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.