Jackson does not support deserializing new Java 9 unmodifiable collections
See original GitHub issueDescribe the bug Java 9 introduced new unmodifiable collection APIs. For instance, List.of.
Today, Jackson has a special deserializer for Collections.unmodifiableList but not for these new classes: https://github.com/FasterXML/jackson-databind/blob/a64e1bfd7ced17c2e19e73da1a00f3e679011fec/src/main/java/com/fasterxml/jackson/databind/deser/impl/JavaUtilCollectionsDeserializers.java#L81
Version information 2.11.2
To Reproduce
@Test
public void testUnmodifiableList() throws JsonMappingException, JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTypingAsProperty(
new NoCheckSubTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL,
"@class"
);
final List<String> list = Collections.unmodifiableList(Collections.singletonList("a"));
final String actualJson = mapper.writeValueAsString(list);
System.out.println(actualJson);
final List output = mapper.readValue(actualJson, List.class);
System.out.println(output);
}
@Test
public void testJava9UmodifiableList() throws JsonMappingException, JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTypingAsProperty(
new NoCheckSubTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL,
"@class"
);
final List<String> list = List.of("a");
final String actualJson = mapper.writeValueAsString(list);
System.out.println(actualJson);
final List output = mapper.readValue(actualJson, List.class);
System.out.println(output);
}
@Test
public void testJava9ListWrapped() throws JsonMappingException, JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTypingAsProperty(
new NoCheckSubTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL,
"@class"
);
final List<String> list = Collections.unmodifiableList(List.of("a"));
final String actualJson = mapper.writeValueAsString(list);
System.out.println(actualJson);
final List output = mapper.readValue(actualJson, List.class);
System.out.println(output);
}
testJava9UmodifiableList fails. The other 2 pass.
Expected behavior I would think the new classes are added as additional aliases as candidates for special deserialization.
Unfortunately, I think this is tricky for two reasons:
- These are Java 9 classes and Jackson supports a lower minimum Java version. I’m not sure if there’s a way to add them without breaking backwards compatibility or introducing a new Java 9 add-on library, like there exists for Java 8.
- There are multiple classes. For List.of, there seem to be 3 different ones depending on the number of arguments:
- Empty list if 0 arguments.
- List12 if 1 or 2 arguments.
- ListN if more than 2 arguments. Source: https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/java/util/List.java#l1031
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:6 (4 by maintainers)
Top Results From Across the Web
jackson serializing Collections.unmodifiable* - Stack Overflow
UnmodifiableCollection you won't be able to deserialize it. You probably don't need to to use unmodifiable collection to be serialized. What is ...
Read more >Security update for jackson-databind, jackson-dataformats ...
... Jackson does not support deserializing new Java 9 unmodifiable collections + Allocate TokenBuffer instance via context objects (to allow ...
Read more >Frequently Asked Questions - XStream
registerConverter(new JavaFieldConverter(javaClassConverter, mapper){});. My implicit collection is suddenly null after deserialization instead of empty! By ...
Read more >JsonDeserializer (jackson-databind 2.12.1 API) - javadoc.io
Abstract class that defines API used by ObjectMapper (and other chained JsonDeserializer s too) to deserialize Objects of arbitrary types from JSON, ...
Read more >Jackson: java.util.LinkedHashMap cannot be cast to X
Second, when Jackson attempts to deserialize an object in JSON but no target type information is given, it'll use the default type: ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Ok, had a chance to look a bit into this. I agree with notes on 2 main challenges, but there is also third immediate problem wrt tests: type for
List
is actuallyfinal
which is what sort of breaks the test since:final
– will result in no type information being added, BUTList
– is NON-FINAL and as such no type information is exceptedso test would fail even if special handling was added.
For now I think I can at least add failing test(s), under
src/test-jdk14/
to allow reproducing the issue, in case someone has time to look deeper into possible solutions.Hi, 2.13.0 doesn’t seem to work with
Set.of()
and I don’t see any tests for it, there’re only forList.of()
andMap.of()
.