-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Support for JDK 14 record types (Jackson 2.12.0) #2709
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
Comments
Can Jackson make use of the actual (parameterized) record constructor? That'd definitely be preferable over injecting values into private record fields. |
@gunnarmorling yes that would be optimal: Kotlin module does that for data classes at least, I think Scala module similarly for case classes. That's where detecting Record types would help, to forcible enable use of constructor (and possibly figure out main one, if class definition has multiple alternatives), without changing behavior of POJO types (where there are backwards-compatibility issues, possible security concerns). |
Re identifying the canonical constructor, this requires a small amout of bespoke logic to collect the component types: https://twitter.com/sormuras/status/1258657911263428608. The biggest challenge I see (without knowing internals of Jackson at all) is that object graphs (records referencing other records referencing other records...) need to be built starting at leaf nodes, so that the inner nodes can be passed to constructors of outer nodes. Is there some logic for that already? |
First attempt at supporting Java 14 records (JEP 359). Records are simple DTO/POJO objects with final fields (components) and accessors. Record's components are automatically serialized and the canonical constructor is used for deserialization. Implementation is still compatible with Java 8 and uses a bit of reflection to access record's components. However the unit tests now require a JDK 14 to run. The basic idea is to make record's components discovered as properties (similar to beans having getters) and to make the canonical constructor accessible via implicit parameter names.
First attempt at supporting Java 14 records (JEP 359). Records are simple DTO/POJO objects with final fields (components) and accessors. Record's components are automatically serialized and the canonical constructor is used for deserialization. Implementation is still compatible with Java 8 and uses a bit of reflection to access record's components. However the unit tests now require a JDK 14 to run. The basic idea is to make record's components discovered as properties (similar to beans having getters) and to make the canonical constructor accessible via implicit parameter names.
@gunnarmorling I am not sure I (yet) understand the specific issue, but I suspect answer is no: Jackson simply iterates over constructors it sees and has to determine it in "shallow" manner (deserializers for delegated type are resolved in separate passes to allow for cyclic type dependencies), without much coupling between levels. Then again, traversing constructors could perhaps be encapsulated without most of databinding being aware of the logic. Still, if there are multiple non-zero-arg constructors that gets tricky and is not a supported use case yet. |
It might well be there's no problem at all. What I was thinking of was this case:
As records are immutable, the nested |
Hi @gunnarmorling, is it
|
First attempt at supporting Java 14 records (JEP 359). Records are simple DTO/POJO objects with final fields (components) and accessors. Record's components are automatically serialized and the canonical constructor is used for deserialization. Implementation is still compatible with Java 8 and uses a bit of reflection to access record's components. A new Maven profile has been introduced to build JDK14 tests using records, those tests have their own source folder, this way it is still possible to build with JDK < 14. The basic idea is to make record's components discovered as properties (similar to beans having getters) and to make the canonical constructor accessible via implicit parameter names.
@youribonnaffe, yes it is. Nice, seems records are nicely supported than in Jackson already 👍 |
Would it be possible to support method local records as well? Currently in
|
Until official record support here is an annotation introspection that can be used as workaround:
|
Hi @jedvardsson, it looks similar to https://gist.github.com/youribonnaffe/03176be516c0ed06828ccc7d6c1724ce which was one of my first attempt to support it |
Some progress here: was able to make serialization work as expected by introduction of new handler (see #2800) and Record-specific branching with default one. |
And there! It is done -- initial implementation at any rate. If anyone wants to check it out that would be highly appreciated. The highest value contribution would probably be addition of tests in |
With the support of Java records, a Maven build profile has been introduced to Java 14 language and preview features. This was done in 2.12 branch, just porting it back to master as records are supported there too.
Released as part of Jackson 2.12.0. |
Very nice. Is the usage documented somewhere? |
Hello @vogella, Do you think it would be worth its own documentation? Also @cowtowncoder published a blog post on the latest release where the feature is mentioned: https://cowtowncoder.medium.com/jackson-2-12-features-eee9456fec75 |
(note: created based on FasterXML/jackson-future-ideas#46)
With JDK 14 Java will get Record type of classes. While it appears that they can already be used with right set of configuration options, it would probably make sense to add explicit support to maybe use different auto-detect defaults.
Support should be done in a way that does not require JDK 14 dependency by
jackson-databind
(that is a leap too far even for 3.0 at least as of May 2020): either so thatjackson-module-jdk14
orjackson-datatype-jdk14
, depending).Marking tentatively as 3.0, but may be moved to a 2.x version if and when someone actual works on this.
The text was updated successfully, but these errors were encountered: