Skip to content

Jackson does not support deserializing new Java 9 unmodifiable collectionsΒ #2900

@TheSpiritXIII

Description

@TheSpiritXIII

Describe 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:

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:

  1. 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.
  2. There are multiple classes. For List.of, there seem to be 3 different ones depending on the number of arguments:

Metadata

Metadata

Assignees

No one assigned

    Labels

    JDK11Features that need JDK11 (and/or support JDK11)has-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions