[JAVA-4309] NullPointerException creating GraalVM native image Created: 22/Sep/21 Updated: 28/Oct/23 Resolved: 27/Sep/21 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Internal |
| Affects Version/s: | None |
| Fix Version/s: | 4.3.3 |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Renārs Kudiņš | Assignee: | Jeffrey Yemin |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | external-user | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Documentation Changes: | Not Needed |
| Description |
|
Method sun.nio.ch.DirectBuffer.cleaner() does not take any parameters in Java 8, code https://github.com/mongodb/mongo-java-driver/blob/master/driver-core/src/main/com/mongodb/internal/connection/tlschannel/util/DirectBufferDeallocator.java#L54 passes null array as a paramter to this method. This leads to NullPointerException when building native image with GraalVM (see below for stacktrace). Steps to reproduce error:
|
| Comments |
| Comment by Jeffrey Yemin [ 27/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
I went ahead and made the change to work around the GraalVM issue. We'll release it in the next 4.3 patch as well as 4.4.0. | ||||||||||||||||||||||||||||||||||
| Comment by Githook User [ 27/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
Author: {'name': 'Jeff Yemin', 'email': 'jeff.yemin@mongodb.com', 'username': 'jyemin'}Message: Removed unnecessary parameter to Class.getMethod As per https://github.com/marianobarrios/tls-channel/commit/f6702edfbc4f1d482f8c36561d0dde75549b357c.
| ||||||||||||||||||||||||||||||||||
| Comment by Githook User [ 27/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
Author: {'name': 'Jeff Yemin', 'email': 'jeff.yemin@mongodb.com', 'username': 'jyemin'}Message: Removed unnecessary parameter to Class.getMethod As per https://github.com/marianobarrios/tls-channel/commit/f6702edfbc4f1d482f8c36561d0dde75549b357c.
| ||||||||||||||||||||||||||||||||||
| Comment by Jeffrey Yemin [ 25/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
I also opened https://github.com/marianobarrios/tls-channel/issues/27, where this code is vendored from. | ||||||||||||||||||||||||||||||||||
| Comment by Renārs Kudiņš [ 23/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
@Jeffrey Yemin, yes if null argument is omitted then image is created and running it fails with
This is expected as I am running Java 11.
My setup:
If I run following code:
Image is not created.
I am not very familiar with GraalVM native image builds (first time trying to create one), but my guess is that this could be related to following from https://www.graalvm.org/reference-manual/native-image/Reflection/
I have also reported to Oracle GraalVM project https://github.com/oracle/graal/issues/3815
| ||||||||||||||||||||||||||||||||||
| Comment by Jeffrey Yemin [ 22/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
I'm not able to run sbt clean compile 'show graalvm-native-image:packageBin' and I'm not sure why. If you'd like to move this case along, could you try an experiment for me? See what GraalVm does with just this code:
Does it create the native image successfully? | ||||||||||||||||||||||||||||||||||
| Comment by Jeffrey Yemin [ 22/Sep/21 ] | ||||||||||||||||||||||||||||||||||
|
Very interesting report, and I'm surprised this is the first time this has been reported, as I've seen lots of usage of the Java driver with GraalVM, most notably in the Quarkus project. I'm wondering whether you're using any options that are not enabled by most others. Do you know which of these is triggering the analysis?
It's possible that if you disable one of them, you'll be able to work around this. In terms of why this is happening: I don't have a lot of familiarity with GraalVM, but I wonder whether this is due to a difference in implementation. In the standard Oracle/Open JDK, it's perfectly fine to pass null as the second parameter to Method.getMethod. The method is defined with a varargs parameter:
so the null that the driver is passing is just indicating that there are no parameters expected to the method that is being looked up. In OpenJDK, if you follow the code down it eventually gets here:
So it's handling the null value that the driver is passing. I wonder if GraalVM is doing something different in its implementation of getMethod that's triggering the NPE. The other interesting thing is that at runtime this code won't actually be invoked at all, since the call is wrapped in a conditional:
This all said, I don't actually know why the driver code is passing null here at all, rather than just doing:
I'll investigate that question a little further, and get back to you. But for now, can you see if you can work around this by changing graalVMNativeImageOptions? |