Auto detect records for Jackson serialization#993
Conversation
9c6748e to
7733c63
Compare
Would it make sense to have a Java 17-based test module to verify Java 17-related Airlift behavior? |
Yes - I think it does. However, I would do it as a separate PR. It will make the CI more complicated. |
7733c63 to
c8e8355
Compare
| private static boolean isRecord(Class<?> clazz) | ||
| { | ||
| Class<?> superclass = (clazz != null) ? clazz.getSuperclass() : null; | ||
| return (superclass != null) && superclass.getName().equals("java.lang.Record") && ((clazz.getModifiers() & Modifier.FINAL) != 0); |
There was a problem hiding this comment.
I think Modifier.isFinal(clazz.getModifiers()) is the preferred way
d6bb735 to
358d307
Compare
358d307 to
5d445a3
Compare
| public class RecordAutoDetectModule | ||
| extends SimpleModule | ||
| { | ||
| private static final Optional<MethodHandle> isRecord; |
There was a problem hiding this comment.
Make uppercase since this is a constant
| public Introspector() | ||
| { | ||
| recordVisibilityChecker = VisibilityChecker.Std.defaultInstance() | ||
| .withGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY) |
There was a problem hiding this comment.
Is it intended that this is duplicated below?
|
|
||
| public Introspector() | ||
| { | ||
| recordVisibilityChecker = VisibilityChecker.Std.defaultInstance() |
| { | ||
| try { | ||
| // TODO replace with real call to isRecord() when Airlift is on Java 14+ | ||
| return (Boolean) methodHandle.invoke(ac.getRawType()); |
There was a problem hiding this comment.
You should be able to use invokeExact() here and cast to (boolean) to avoid boxing.
| try { | ||
| //noinspection JavaLangInvokeHandleSignature | ||
| methodHandle = MethodHandles.lookup() | ||
| .findVirtual(Class.class, "isRecord", methodType(Boolean.TYPE)); |
There was a problem hiding this comment.
One more nit: use boolean.class here for the primitive class reference
Currently, record serialization requires annotating records with `@JsonAutoDetect(getterVisibility = PUBLIC_ONLY)`. This is a nuisance and can be hard to debug when it's forgotten (Jackson serializes to an empty object when it's missing). Add a Jackson module that auto-detects Records and sets the visibility to match the annotation. Note: Airlift is currently at Java 11 so record detection is not ideal (though it mimics what the JDK does). Once Airlift is at Java 17 it can be updated and a test can be added.
5d445a3 to
d6dc459
Compare
Currently, record serialization requires annotating records with
@JsonAutoDetect(getterVisibility = PUBLIC_ONLY). This is a nuisanceand can be hard to debug when it's forgotten (Jackson serializes
to an empty object when it's missing).
Add a Jackson module that auto-detects Records and sets
the visibility to match the annotation. Note: Airlift is
currently at Java 11 so record detection is not ideal (though it
mimics what the JDK does). Once Airlift is at Java 17 it can
be updated and a test can be added.
Note: I tested this in Java 17 project independently to verify that it works.