eclipse-ee4j / eclipse-ee4j/yasson
Custom serializers/deserializers and adapters ignored for Map keys (and values).
- Dominant language
- Java
- Stars
- 218
- Forks
- 109
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 9
Description
**Describe the bug**
Similar to issue #587, which has been fixed in v3.0.3, custom serializers/deserializers and adapters are also ignored for map keys and values. Consider a map with a custom key and an adapter that translates this custom key to a string, then the map should be serialized into a JSON object
```
{
"key":"value"
}
```
rather than an array of key/value objects.
```
[
{
"key":{"value":"key"},
"value":"value",
}
]
```
**To Reproduce**
The unit test below allows reproducing the issue.
```
package maps;
import static jakarta.json.bind.JsonbBuilder.create;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.json.bind.annotation.JsonbTypeAdapter;
public class MapTest {
public static class CustomKeyAdapter implements JsonbAdapter {
@Override
public String adaptToJson(CustomKey key) throws Exception {
return key != null ? key.toString() : null;
}
@Override
public CustomKey adaptFromJson(String s) throws Exception {
return s != null && s.length() > 0 ? new CustomKey(s) : null;
}
}
// A simple custom key that can be translated into a string.
@JsonbTypeAdapter(CustomKeyAdapter.class)
public static class CustomKey {
private String value;
public CustomKey(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@Test
public void marshalMap() {
Map map = new HashMap<>();
map.put(new CustomKey("key"),"value");
Jsonb jsonb = create();
String json = jsonb.toJson(map);
assertEquals("{\"key\":\"value\"}", json);
}
}
```
The unit test fails with the following error message:
```
org.junit.ComparisonFailure: expected:<[{"key":"value"}]> but was:<[[{"key":{"value":"key"},"value":"value"}]]>
```
**Expected behavior**
Serialize maps into a JSON object if the custom key type can be adapted to a string.
**System information:**
- OS: [Mac, Ubuntu]
- Java Version: [19]
- Yasson Version: [3.0.3]
**Additional context**
In a [comment in issue 587](https://github.com/eclipse-ee4j/yasson/issues/587#issuecomment-1673461840) it was already pointed out that the fix should be applied to maps and arrays too.
Contributor guide
Research direction
Start with the supplied maps.MapTest and its Jsonb.toJson(map) reproduction, then trace the map serialization path used by JsonbBuilder.create(). Confirm the fix with the provided adapter and assert that an adaptable custom key produces {"key":"value"} rather than an array of key/value objects.
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
- Clearly specified
- Newbie friendliness
- 55/100