-
-
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
Allow (de)serializing records using Bean(De)SerializerModifier
even when reflection is unavailable
#3417
Conversation
Ok. Hmmh. I really need to think this through. On plus side I would love to help things work better on Graal/native. On downside, problems you listed are non-trivial... I think exception message improvements could make me more positive about PR. But I realize that if one blocks exceptions there may not be good way to signal (likely) nature of the problem through the call stack. |
I will spend some time tomorrow to take a stab at general graal error message improvements. While this PR makes the messages worse ofc, this is already the status quo for non-record classes – maybe it's possible to improve error handling for all classes that have reflection info missing, and solve the messages for records while I'm at it. |
@cowtowncoder take a look at the changes i added. Now, the error messages have additional information when running in native image mode and when no reflection data is detected. I've also amended https://github.com/yawkat/graal-record-jackson/blob/master/src/test/java/RecordTest.java with tests for this (still don't know how to get these tests into this PR) |
Oh and I added a dependency to graal-sdk to get the proper information. It is |
pom.xml
Outdated
@@ -72,6 +72,12 @@ | |||
<artifactId>jackson-core</artifactId> | |||
<version>${jackson.version.core}</version> | |||
</dependency> | |||
<dependency> |
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.
Add a brief comment referring to this PR, purpose.
Ok, so, ideally it should be fine to have
Basically I'd just want to minimize warnings on various platforms in case of missing functionality. Does this make sense? I think we can avoid even attempt to trigger class loading on pre-Record platforms (android), to keep logs clean. :) |
@cowtowncoder Well, I asked the substratevm team at oracle, and it is not necessary after all to depend on graal-sdk. I've changed the code to depend on System.getProperty instead. This is also supported (the property name and value are guaranteed not to be changed in future graal versions). Does this work for you? |
@cowtowncoder can you take another look at this please |
Hi @yawkat -- apologies about slowness on my part; will try to review later today; adding to my TODO list. |
Looks good as far as I can see, will mege. |
Thanks! |
First of all, apologies for not reporting this issue separately before making a PR. I had to write the patch anyway for internal bureaucracy reasons, so I couldn't wait for more feedback on whether this is the right approach to fix this issue.
With graal native image, reflection information for records is opt-in. When it is missing, jackson will report a bad definition:
(similar for deserialization)
This is usually fine, but when the
ObjectMapper
is configured with aBeanDeserializerModifier
andBeanSerializerModifier
that implement access to the record components on their own, this is an issue. The error will happen even if the modifiers could (de)serialize a record. A very simple test case is available here, just run./gradlew nativeTest
: https://github.com/yawkat/graal-record-jackson/blob/master/src/test/java/RecordTest.javaThis PR changes
JDK14Util
recordComponents
to instead returnnull
if the call fails due to a graal native image error. It compares the error class, which is unfortunately the only way to do this right now, according to the graal team at oracle. Downstream users of this class are also changed to account for this.However I see two issues with this PR. First, the errors people get when they don't use a modifier are now worse. For serialization:
For deserialization:
iirc this is consistent with what happens with non-record beans when reflection information is unavailable. But the failure mode is certainly more confusing than it is without this patch, which may lead to users not realizing they have to enable reflection for the record classes.
The second issue is testing this. I don't see a sensible way to add native image tests to jackson-databind, so this patch does not have a unit test. This also means it's very easy to introduce a regression here, should this code be touched again.