Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
TheSpiritXIII opened this issue Oct 21, 2020 · 6 comments
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue JDK11 Features that need JDK11 (and/or support JDK11)
Milestone

Comments

@TheSpiritXIII
Copy link

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:
@TheSpiritXIII TheSpiritXIII added the to-evaluate Issue that has been received but not yet evaluated label Oct 21, 2020
@cowtowncoder cowtowncoder added the JDK11 Features that need JDK11 (and/or support JDK11) label Oct 21, 2020
@cowtowncoder
Copy link
Member

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 actually final which is what sort of breaks the test since:

  1. During serialization, actual type -- which is final -- will result in no type information being added, BUT
  2. During deserialization, requested type -- List -- is NON-FINAL and as such no type information is excepted

so 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.

@cowtowncoder cowtowncoder added has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue and removed to-evaluate Issue that has been received but not yet evaluated labels Nov 10, 2020
@cowtowncoder
Copy link
Member

cowtowncoder commented Jan 29, 2021

Quick note: I think changes from #3009 may have helped (or will help), although there is still at least one failure -- but that is the variant problem wrt final.

@TheSpiritXIII would it be easy to test against 2.12.1 to see if the fix mentioned helps?

@cowtowncoder
Copy link
Member

Ok, so I fixed the main issue for 2.13.0 and when type id is included List.of() as well as Map.of() sourced containers should handle as expected.

The problem wrt test and inclusion -- that implementation types are final, preventing application of Default Typing -- is something that I don't quite know how to tackle at this point.

@joakime
Copy link

joakime commented Mar 2, 2021

When will 2.13.0 be release?

@kupci
Copy link
Member

kupci commented Mar 2, 2021

When will 2.13.0 be release?

Per below, towards end of Q2 or early Q3 ( so June/July 2021)
https://github.com/FasterXML/jackson-future-ideas/wiki/Jackson-Work-in-Progress

@Sam-Kruglov
Copy link

Hi, 2.13.0 doesn't seem to work with Set.of() and I don't see any tests for it, there're only for List.of() and Map.of().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue JDK11 Features that need JDK11 (and/or support JDK11)
Projects
None yet
Development

No branches or pull requests

5 participants