Simplifying native-image generation with Maven plugin and embeddable configuration

Paul Wögerer
Mar 19, 2019 · 6 min read

In this blog post we show two features recently added to GraalVM to simplify the generation of native images. One is a Maven plugin so you can include the native image generation in your build without calling the command line utilities manually. Then we look at native-image.properties as a way to include the configuration for your library in the jar file to avoid manual configuration.

Building netty-plot with native-image-maven-plugin

This blog post shows you how to use Maven to easily build native images. If you are using GraalVM as your JAVA_HOME it is sufficient to just add:

native-image-maven-plugin pom.xml snippet

into the <plugins> section of your pom-file. For the previously published native-netty-plot example the above is sufficient to allow maven to build the native-image for us. Running mvn package will now give us:

`mvn package` output of native-image-maven-plugin

The output shows that the plugin figured out what jar-files it needs to pass to native-image and what the executable main-class should be (com.oracle.svm.nettyplot.PlotServer). Once mvn package completes, you can find the executable netty-plot in the target directory of the maven project.

Since the Maven integration is available in almost any IDE you having a maven plugin means you can generate native images without leaving it:

Image for post
Image for post
Generating native images without leaving your IDE with the maven plugin

Plugin customization

Configuration parameter <mainClass>

  • <maven-shade-plugin> <transformers> <transformer> <mainClass>
  • <maven-assembly-plugin> <archive> <manifest> <mainClass>
  • <maven-jar-plugin> <archive> <manifest> <mainClass>

If it cannot find a proper definition of a main class in any of these locations you can add a <mainClass> in the <configuration>node of the plugin to specify a custom main class.

Configuration parameter <imageName>

Configuration parameter <buildArgs>

Example configuration

<configuration> node with <buildArgs>

to the definition of the native-image-maven-plugin in your pom-file.

Using maven-plugin with GraalVM Enterprise Edition:

Using maven-plugin without GraalVM:

Updating native-image-maven-plugin to new GraalVM release

No further steps are required. Maven will take care of the rest!

⚠ Please note that in this scenario using macro options like--language:<name>or --tool:<name>will not work as they require a full GraalVM release to be used as your JAVA_HOME. Also be aware that if a newer GraalVM release has changes that depend on a newer JVMCI enabled JDK you will have to update the JVMCI enabled JDK as well … caveat emptor.

Composable native-image.properties

native-image -jar target/netty-plot-0.1-jar-with-dependencies.jar

is sufficient to build the image. Before, building an image that contains Netty always required the use of additional command line options. Usually it was something like:

-H:ReflectionConfigurationResources=reflection-config.json \
--delay-class-initialization-to-runtime=io.netty.handler.codec.http.HttpObjectEncoder

The reason this works now is that these extra flags can now be embedded in the jar-file itself. Looking into the native-image.properties file from above shows what extra flags are passed to native-image when netty-plot-0.1-jar-with-dependencies.jar is on the image classpath.

META-INF/native-image/com.oracle.substratevm/netty-plot/native-image.properties

Here again we find among other things the familiar options needed for building images that contain Netty. Notice the use of ${.} in the above file. This is a convenient feature of native-image.properties files that allows to refer to the location the native-image.properties file resides in. This way it is possible to conveniently specify resource locations relative to the location of a native-image.properties file. In the above case ${.} gets expanded to META-INF/native-image/com.oracle.substratevm/netty-plot.

Making Java libraries native-image compatible by default

In the example of Netty, if we had an artifact io.netty:netty-allthat contains:

META-INF/native-image/io.netty/netty-all/reflection-config.json
META-INF/native-image/io.netty/netty-all/native-image.properties

in addition to the substitutions from com.oracle.svm.nettyplot.NettySubstitutionsthen Netty could be used with native-image out of the box. The other native-image.properties file for our netty-plot example would then only contain options that netty-plot itself needs:

netty-plot native-image.properties after removing Netty specific bits

In addition to that, we could get rid of the com.oracle.substratevm:svm dependency in our pom file

Netty-specific native-image dependency in netty-plot pom.xml

which is currently only needed because NettySubstitutions depend on it.

💡 About <scope>provided</scope>

The <scope>provided</scope> used above is important because the substitutions are only needed during image building where com.oracle.substratevm:svm is provided by the image builder itself. If this scope definition is omitted Maven would put com.oracle.substratevm:svm and all its transitive dependencies into the jar file when it creates an uber-jar. Clearly we wouldn't want that to happen!

If io.netty:netty-all would contain all the specifics needed to allow using it in native-images the above dependency in netty-plot could be reduced to

netty-plot depends on org.graalvm.nativeimage API

because netty-plot itself only depends on our official org.graalvm.nativeimage API.

Conclusion

These two are a quality of life improvements that allow the ecosystem to take advantage of the GraalVM native images and ahead of time compilation. Download GraalVM and give it a try: https://www.graalvm.org/downloads.

See a good feature missing or have any other feedback? Please reach out to us, leave an issue at the GraalVM GitHub repo or contact us any other way!

graalvm

GraalVM team blog - https://www.graalvm.org

Paul Wögerer

Written by

Researcher at Oracle Labs. Working on GraalVM native image generation (Substrate VM). Opinions are my own.

graalvm

graalvm

GraalVM team blog - https://www.graalvm.org

Paul Wögerer

Written by

Researcher at Oracle Labs. Working on GraalVM native image generation (Substrate VM). Opinions are my own.

graalvm

graalvm

GraalVM team blog - https://www.graalvm.org

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store