Support for GraalVM Native Images
See original GitHub issueFeature Request
It would be nice to make the library compatible with GraalVM out of the box.
Is your feature request related to a problem? Please describe
Currently is not possible to convert a Java app with Lettuce to a GraalVM native image.
Describe the solution you’d like
The library should include all the necessary GraalVM configuration so users don’t need to do anything on their own applications. This may also imply doing so modifications in the library to make it compatible.
Describe alternatives you’ve considered
I’ve been playing a little bit with this and I’ve create a simple plain Java application that uses the library to connect to Redis and execute a few commands. The application is available at: https://github.com/ilopmar/redis-lettuce-graalvm, please take a look at the README about how to run the app.
I don’t have experience neither with Redis nor the library so I’m pretty sure that the code can be improved a lot. Please feel free to do it 😃
Things to consider:
-
I’ve used the GraalVM Tracing Agent (see this) to help with the generation of all the GraalVM configuration. Take a look at the files
jni-config.json
,proxy-config.json
andreflect-config.json
here. -
At this moment, with the only things that my sample application uses from the library, all those previous GraalVM reflection configuration is needed. I’m not 100% sure if all of that is really necessary because I don’t know the internals of the library.
-
It is only possible to generate the native image adding the flag
--report-unsupported-elements-at-runtime
(see this). The GraalVM team discourage the use of that option so probably some changes in the library are needed to being able to remove it. -
I also needed to add
org.hdrhistogram:HdrHistogram
andorg.latencyutils:LatencyUtils
dependencies to be able to run the native-image. Without them the process fails when starting with the following error. I don’t know why they are mandatory because I’m able to run the application with the JVM without them.
$ ./redis-lettuce-graal
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.oracle.svm.core.hub.ClassInitializationInfo.initialize(ClassInitializationInfo.java:290)
at java.lang.Class.ensureInitialized(DynamicHub.java:499)
at io.lettuce.core.resource.DefaultClientResources.<init>(DefaultClientResources.java:181)
at io.lettuce.core.resource.DefaultClientResources$Builder.build(DefaultClientResources.java:530)
at io.lettuce.core.resource.DefaultClientResources.create(DefaultClientResources.java:231)
at io.lettuce.core.AbstractRedisClient.<init>(AbstractRedisClient.java:97)
at io.lettuce.core.RedisClient.<init>(RedisClient.java:90)
at io.lettuce.core.RedisClient.create(RedisClient.java:139)
at example.App.main(App.java:9)
Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: pauseDetectorWrapper
at java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:127)
at java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:110)
at io.lettuce.core.metrics.DefaultCommandLatencyCollector.<clinit>(DefaultCommandLatencyCollector.java:52)
at com.oracle.svm.core.hub.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:350)
at com.oracle.svm.core.hub.ClassInitializationInfo.initialize(ClassInitializationInfo.java:270)
... 8 more
Caused by: java.lang.NoSuchFieldException: pauseDetectorWrapper
at java.lang.Class.getDeclaredField(DynamicHub.java:2070)
at java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:122)
A good starting point could be to add more different usages of the library (which I don’t know) to the sample aplicaiton and try to generate the native image. If it works maybe you can include that generated configuration in the library jars so users don’t need to.
Also the documentation should be updated because, when I added a Command
(see this) I also needed to include it in proxy-config.json
(see this) and in reflect-config.json
(see this). I’m not really sure if the library could create that configuration automatically for the users, so at least, for a first version of the GraalVM support this should be documented.
Teachability, Documentation, Adoption, Migration Strategy
With the changes to support GraalVM included in the library, users would be able to convert their applications that use it to GraalVM native-images. Also frameworks like Micronaut, Spring,… and other would also benefit from this.
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (7 by maintainers)
Top GitHub Comments
5.3.2 is scheduled for Mid/Late July. Thanks everyone for your kind support. Closing this ticket as solved.
Excellent! Thank you very much for your help. I’ll include all the GraalVM configuration in Micronaut-Redis and when you release next version I’ll remove it! 😃