eclipse-ee4j / eclipse-ee4j/yasson

Custom serializers/deserializers and adapters ignored for Map keys (and values).

Open
#649 0 comments 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**
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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.