Apache Geronimo Arthur is a new Apache Geronimo subproject. You probably heard about Apache Geronimo in the ecosystem of JavaEE/JakartaEE and Microprofile but what is generally less known is that this project hosts some utilities. The historical one is XBean which is a container toolkit (generic factories, classpath scanning etc...). Geronimo got last week a new addition: Arthur.

Arthur targets GraalVM and in particular native-image tool. Arthur overall goals are to:

  1. Wrap native-image in a ready to run plugins (typically a Maven Plugin in current version),
  2. Run a pre-execution chain which will generate the right configuration (and optionally files) for native-image.

In other words, Arthur aims at simplifying the work to make a Java program native. It can be compared with Quarkus of Read Hat/IBM but it is slightly different in the sense it stick to its primary role to wrap GraalVM native-image and does not try to build a new container or libraries aside existing ones but rather to stick to what you are used to already and just simplify your build to a native binary.

Before going into the details of Arthur, I'd like to remind that making a Java program native with Graal stays AOT (Ahead of Time) so it comes with limitations and will be less powerful than staying on a pure JVM, however it will also save a lot of boot time and runtime memory until the JVM catches up (CDS, new GC etc...) which should happen in a lot of years and will require some architectural changes (in classloading for example) so investing in Graal now for Kubernetes containers can be worth pretty quickly.

Arthur in 5 mn

Assuming your program can be converted with native-image and you are using a Maven build, it can be configured as simply as a plugin definition:

<plugin>
    <groupId>org.apache.geronimo.arthur</groupId>
    <artifactId>arthur-maven-plugin</artifactId>
    <version>${arthur.version}</version>
    <configuration>
        <main>org.company.Main</main> (1)
    </configuration>
</plugin>
  1. The minimum configuration is the entrypoint of your application.

Once you defined this plugin you can make your Main native using:

mvn package arthur:native-image

You probably noticed that no GraalVM HOME or other variable was needed, this is because the Arthur Maven plugin is able to download GraalVM if it is not explicitly configured and to use the downloaded VM automatically. Indeed it caches it in your local repository to avoid this download latency all the time and ensure you can recover from a change in download links.

Go further with Arthur

Arthur has a lot more feature and I'll probably come back about how to write an extension with your own framework or add a custom GraalVM integration when needed without modifying your application vanilla Java version, but one simple but very neat feature of Arthur Maven plugin is way more simple than that: it is the inline native-image configuration. It enables you to configure native-image directly in your pom.xml and avoid to generate a ton of .json files or split your build accross multiple folders. Here is an example adding resource bundles, dynamix proxies (java.lang.reflect.Proxy) through the plugin configuration and also configuring some native-image options (like --initialize-at-build-time) directly in a pom:

<plugin>
    <groupId>org.apache.geronimo.arthur</groupId>
    <artifactId>arthur-maven-plugin</artifactId>
    <version>${arthur.version}</version>
    <configuration>
        <main>org.talend.components.jdbc.graalvm.MainTableNameInputEmitter</main>
        <initializeAtBuildTime>
            <initializeAtBuildTime>org.h2.Driver</initializeAtBuildTime>
            <initializeAtBuildTime>org.company.MyProxyInterface</initializeAtBuildTime>
        </initializeAtBuildTime>
        <bundles>
            <bundle>
                <name>org.company.MyProxyInterface</name>
            </bundle>
        </bundles>
        <dynamicProxies>
          <dynamicProxy>
              <classes>org.company.MyProxyInterface</classes>
          </dynamicProxy>
        </dynamicProxies>
    </configuration>
</plugin>

The pom being the entrypoint of any Maven build, it is very natural to put all its configuration in it, therefore being able to abstract native-image command and store its configuration with the rest of your build is very important in the time.

Bonus command

Before leaving this high level presentation, I want to mention that Arthur Maven plugin is also able to either generate a Docker image published locally on your daemon or remotely on a registry (in this last case it does not even require to have maven on the machine, it just uses HTTPS!).

If you take the previous configurations, you can run:

mvn package \
  arthur:native-image \
  arthur:docker

And it will published a minimal image with the built binary, ready to deploy!

 

Happy (cloud-)nativification!

From the same author:

In the same category: