-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add streamlined sealed class polymorphic de/serialization #3549
Add streamlined sealed class polymorphic de/serialization #3549
Conversation
#3102 seems to be the issue that is breaking the Record tests |
src/main/java/com/fasterxml/jackson/databind/jdk17/JDK17Util.java
Outdated
Show resolved
Hide resolved
// of Record fields. | ||
//[databind#3102]: fails on JDK 16 which finally blocks mutation | ||
//of Record fields. | ||
@Ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only the first of these tests fails - can you just ignore the one that fails?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, and that was the first thing I tried. But the @Ignore
only seems to have any effect if it's applied to the whole class. I admit that I don't understand why. I just tried it again and got the same result. Please check my math here because I agree that would be the better solution. I would be happy to be wrong!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, jackson still uses junit3 as opposed to junit4 (or even junit5) - so that might explain why the Ignore annotation doesn't work at the test level - it works well in junit4 style (where you annotate methods with @Test
).
Could you move the failing tests to the com.fasterxml.jackson.databind.failing package of test-jdk14? Just the failing tests, not the full test classes. So you can copy the full class to com.fasterxml.jackson.databind.failing but then remove the tests that work and go back to the original class and remove the broken test(s).
The tests in the 'failing' package should be ignored when you run the build with mvn from command line.
import com.fasterxml.jackson.annotation.JsonSetter; | ||
import com.fasterxml.jackson.annotation.Nulls; | ||
import com.fasterxml.jackson.databind.BaseMapTest; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.ObjectReader; | ||
import com.fasterxml.jackson.databind.exc.InvalidNullException; | ||
|
||
@Ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again - can you ignore just the individual tests that fail?
// [databind#2992] | ||
public void testNamingStrategy() throws Exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you use @Ignore
like the other tests you disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you move this single test (not full class) to failing package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and uncommented when it is moved
// [databind#3079]: Should be able to Record value directly | ||
public void testDirectRecordUpdate() throws Exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use @Ignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you move this single test to the failing package?
src/test-jdk17/java/com/fasterxml/jackson/databind/jdk17/SealedBasicsTest.java
Outdated
Show resolved
Hide resolved
Thanks for the feedback, @pjfanning! That was an eagle-eyed code review. Regarding the other issues, I think we agree much more than we disagree. I was excited to get the changes in front of you all last night, so I communicated poorly. Let me try again with the benefit of a good night's sleep.
So we're in a little bit of a weird situation on this PR, mostly because the project is already in a (slightly, but significantly) weird situation on JDK17. Namely, record deserialization appears to be broken on JDK17 due to platform changes starting in JDK17 that are completely outside this project's control. Here are the options I see for moving forward, FWIW. You guys may (read: probably will) have a better idea.
In my judgment, for what it's worth, Option 3 above is the best way forward. It allows us to divide and conquer what are really two separate problems here: the new sealed class feature and JDK17 support. Practically, I would roll back the changes to the tests, and we would (a) disable the JDK17 build profile temporarily and open an issue about JDK17 if one doesn't exist, and (b) add a build for JDK15/16 in GitHub actions, depending on what we chose above. But I will happily defer to the maintainers' judgment on this (and all) issues. FYI, @cowtowncoder |
One quick note: I think I'd prefer only testing on LTS versions if at all possible. Use of preview never seems to work very well across various tools. Other than this, yeah, challenges seen do suggest that maybe my initial wish for inclusion in core databind is misguided, and that this really should be in a module. |
Got it. If the goal is to stay on LTS releases, then I think the plan to publish JDK17 features as a module for 2.x makes total sense. I have a module version of this ready. I'll clean it up a little bit and share it on one of these threads. I'll happily make any changes to that you guys like, e.g., single vs multiple JDK17 modules, etc. Thank you all! |
src/main/java/com/fasterxml/jackson/databind/AnnotationIntrospector.java
Show resolved
Hide resolved
src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordWithJsonNaming3102Test.java
Outdated
Show resolved
Hide resolved
Thank you for the (very) quick review, @pjfanning! I will get on this feedback first thing in the morning! |
Thank you again for the quick review, @pjfanning! I believe I have addressed your comments in the latest commits. I did find one issue, though: at least on my machine, while tests in the package Please let me know if you disagree with that change (or see any other issues, for that matter), and I'll address them ASAP! |
src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordBasicsTestFailing.java
Outdated
Show resolved
Hide resolved
@sigpwned Let me change the Done. Should allow placement wherever, tests under |
Oof. That was embarassing. I've removed the reference to the Java16 idiom |
Aside from tests I think the approach to take has to be that of stand-alone separate module, starting with 2.x. The practical challenge is then that of spinning up a new one. One approach is that someone creates up a new repo, to look like |
@cowtowncoder I'm comfortable any which way you and @pjfanning want to approach, and will abide by that decision and help however I can. FWIW, I also have a Java 17 module-style approach up and running at sigpwned/jackson-modules-java-17-sealed-classes, in case that's useful. |
And I've probably missed the big question, which is should I be pursuing a PR for the 3.x branch? |
@sigpwned At this point no need for 3.0; I think stand-alone module does for now and later on we can consider what to do there (keep separate or add integrated -- most likely if JDK baseline was 17) |
Hi! What about this PR? |
@SimSonic there is no plan to merge. Use |
Thanks a lot, I did not see that module at all... |
No plans to merge in its current form, closing. |
Add streamlined support for sealed class polymorphic de/serialization.
Java 17 sealed classes are required to enumerate their allowed subclasses explicitly. This metadata should allow Jackson to infer the subtypes of a sealed class for polymorphic serialization automatically. Specifically, the following sealed class should handle polymorphic serialization as written:
Note the absence of
@JsonSubTypes
annotation and any (Jackson-specific) repetition of any class names in the code above.This PR should work for JDK8+ through the clever use of reflection. (There was an excellent model to follow in
JDK14Util
!) Sealed classes are detected and handled automatically if run on Java17+.The current build is broken on Java 17. I made the following changes to get the build working on JDK17.
setAccessible
to update (implicitly immutable) record field valuesRecordWithJsonNaming3102Test
RecordWithJsonSetter2974Test
RecordBasicsTest#testNamingStrategy
RecordUpdate3079Test#testDirectRecordUpdate
It appears that JDK17 has a change that breaks (at least some cases of) record deserialization, ostensibly related to disallowing the use of
setAccessible
to change a record instance's (implicitly final) field values. It's not clear to me if and how this can be fixed. I'm happy to handle these broken tests another way in this PR (e.g., including moving them to a separate upstream PR and rebasing this PR), but this at least demonstrates that the sealed classes work and tests pass on JDK17.Per the issue FasterXML/jackson-future-ideas#61