Links: Table of Contents | Single HTML

Chapter 26. GraalVM native-image generation

This chapter describes Jersey's compatibility with GraalVM native image. This functionality is available since Jersey 2.35 and is under development and configuration. For now Jersey provides native image configuration basics for some modules and example on how to really generate native image for an existing application.

26.1. Modules with GraalVM native image support

Currently Jersey provides basic support for native image generation within following modules: jersey-common,jersey-server,jersey-client, jersey-hk2. This support means that most of reflection and resource related settings are extracted into reflect-config and resource-config JSON files to be used while generating a native image. Those files are included in the native image generation process automatically (unless some tricky configuration is applied), so there is no need to include those files manually and/or duplicate their contents in some custom configuration.

26.2. HelloWorld native image generation

The example for the GraalVM native image generation is hidden under examples/helloworld example. To generate native image there it's required to perform some preliminary steps:

Download GraalVM at least 20.3.2 version
Set JAVA_HOME to point to that [GraalVM_HOME]
Perform $JAVA_HOME/bin/gu install native-image because native-image tool is not bundled within GraalVM itself
Download Jersey examples source codes (preferable some released version like 2.35), and go to [path_to_jersey_examples]/examples/helloworld
Run mvn -Pnative-image clean package -DskipTests

If all was correctly performed from previous steps the native image shall be already generated inside the targed folder of the helloworld example with the name helloworld-native and it's possible to run it by

target/./helloworld-native

After it's run, console should print our following output:

                "Hello World" Jersey Example App
                May 27, 2021 1:37:49 PM org.glassfish.jersey.server.wadl.WadlFeature configure
                WARNING: JAX-B API not found . WADL feature is disabled.
                May 27, 2021 1:37:49 PM org.glassfish.grizzly.http.server.NetworkListener start
                INFO: Started listener bound to [localhost:8080]
                May 27, 2021 1:37:49 PM org.glassfish.grizzly.http.server.HttpServer start
                INFO: [HttpServer] Started.
                Application started.
                Try out http://localhost:8080/base/helloworld
                Stop the application using CTRL+C
            

If you see this, you can open given link in browser and check how application actually works. In general we are done here and you can use that example to generate native images for your own projects.

26.3. What's under the cover

For the example above the following command line was used:

                -H:EnableURLProtocols=http,https
                --initialize-at-build-time=org.glassfish.jersey.client.internal.HttpUrlConnector
                -H:+ReportExceptionStackTraces
                --verbose
                --no-fallback
                --report-unsupported-elements-at-runtime
            

This might be useful to generate another native image. It's possible to add another bunch of parameters to the command line (and put those into the native-image.properties file inside of your project). Important parameter here is --initialize-at-build-time (opposite to --initialize-at-run-time) and --no-fallback which says to the native image to generate pure native image with everything bundled inside the image and not just fall back wrapper for JDK.

Another important aspect for generating the native image is the proper listing of reflection classes (classes that use reflection in an application). For those needs, there is a native image agent which helps to generate those lists automatically. In order to generate a list of reflection classes (and JNI classes and resources), it is required to run:

$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=[output_location] -jar [app_name].jar

And afterwords, the [output_location] directory will be created with generated lists (in JSON format). Those files can be included as is into native image generation, but it's very preferable to edit them manually to reduce possible ambiguous classes listings.