-
Notifications
You must be signed in to change notification settings - Fork 32
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
Adding Supports for Records (Groovy) + Passing Record Test. #122
Adding Supports for Records (Groovy) + Passing Record Test. #122
Conversation
@@ -142,6 +143,13 @@ private static void _introspect(Class<?> currType, Map<String, PropBuilder> prop | |||
name = decap(name.substring(2)); | |||
_propFrom(props, name).withIsGetter(m); | |||
} | |||
} else { | |||
// This will allow getters with field name as their getters, like the ones generated by Groovy | |||
boolean isDirectNameGetter = Arrays.stream(currType.getDeclaredFields()).map(Field::getName).anyMatch(f -> f.equals(m.getName())); |
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.
i believe if we get a list of fields & check if there is a field with the same name as current method, then we need to add it as a prop
, this can be optimized, but as of now, its working.
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.
I think this capability needs to be behind Json.Feature
flag since while it makes sense wrt Records (and probably other value types), it can also be unexpected for other users. That is, it changes compatibility.
Other than that it'd make sense to build a map from name to Field
in loop above, to avoid linear scanning for every potential "non-get-getter".
eb9e69e
to
a039df4
Compare
Quick note: if this is meant for Groovy records specifically, should probably file a new separate issue -- #94 is, I think, for Java 17 Record type and require immutability including construction by multi-argument constructor. I also think this should be behind a new |
@@ -0,0 +1,68 @@ | |||
package com.fasterxml.jackson.jr.passing |
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.
Is the new passing
needed to avoid split packages or... ?
If necessary, maybe use com.fasterxml.jackson.jr.ob.groovy
.
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.
my mistake, removed in latest commits.
Yes, this will fix Java14's Records as well as Groovy Records.
Okay so, how should we go on to check which object is a record and which is not, without having access to native internal methods? I tried to do some digging, and found out this: One immediate way that i can think of is to check constructor parameters matching the field names . |
It is possible to detect "Record-ness" of a type, even from JDK 8: jackson-databind does that. Actually detecting something is Record is relatively easy: public static boolean isRecordType(Class<?> cls) {
Class<?> parent = cls.getSuperclass();
return (parent != null) && "java.lang.Record".equals(parent.getName());
} which we could re-purpose. Same might work for Groovy types. Anything fancier (finding canonical constructor, declared properties) gets trickier, but just knowing something is a Record type is quite doable. |
I think that we have a choice, so either:
I guess one could combine things too, to basically default to auto-detecting via (2), but allowing disabling by (1). Not sure how necessary that is. |
Ok, couple of additional notes:
We could, however, also test case of "not Record but has field-name matching getter methods" as surrogates for Records. This assuming we do not want to limit this feature to just Java/Groovy Record types. |
I believe 1st choice is better, since we have the knob to turn this feature off, when working with other libraries, |
…a.nio.file.Path`
… going to throw this time)
9cc4bfc
to
53b9bde
Compare
This failing test, it seems, that the since, the getter is public, we are getting the values, and hence we are able to serialize these items. looks like correct behavior. can you confirm once again? so that I will remove this test. or this is the expected behavior? I didnt really think about |
@@ -145,6 +149,15 @@ private static void _introspect(Class<?> currType, Map<String, PropBuilder> prop | |||
name = decap(name.substring(2)); | |||
_propFrom(props, name).withIsGetter(m); | |||
} | |||
} else if(USE_FIELD_NAME_GETTERS.enabledByDefault()){ |
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.
As with other comment, enabledByDefault()
is not to be used here -- we need actual configuration settings.
There's an example earlier on:
final boolean noStatics = JSON.Feature.INCLUDE_STATIC_FIELDS.isDisabled(features);
that shows expected usage.
Quick request: would it be possible to extract change to add new test module for Groovy classes into separate PR? We already added |
sounds good, let me do that. |
Created a new PR: #128 |
Closing this PR, will start with clean slate, with minimal changes, and formatting. |
Issue : support for records #94
This will enable the introspector to catch Groovy generated getters, and serialize the records.