GraalVM is now joining openjdk (archive), so it’s time to review how to compile java to native code, because it’s so easy!

1. Single File, dependencies in a über jar

Assuming you’ve already installed GraalVM, you have access to native-image.

If you have external dependencies, the easiest is generate a "über jar", and then asking native-image to compile a static binary from it.

2. Example

Let’s try a simple cli program, depending on picocli (archive), a feature-rich library to write cli on the JVM:

import picocli.CommandLine;

import java.util.concurrent.Callable;

@CommandLine.Command(
    name = "hello-cli",
    mixinStandardHelpOptions = true,
    version = "1.0",
    description = "Prints a nice hello")
public class HelloCli implements Callable<Integer>  {

  @Override
  public Integer call() {
    System.out.println("Bien le bonjour, humain.");
    return 0;
  }

  public static void main(String... args) {
    int exitCode = new CommandLine(new HelloCli()).execute(args);
    System.exit(exitCode);
  }
}

Then, we need to generate the über jar, for example with maven-assembly-plugin if you use a pom.xml to describe your dependencies:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <archive>
          <manifest>
            <mainClass>
              com.your.path.HelloCli
            </mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

And then generate that jar:

mvn clean package

Finally, let’s compile our native executable:

native-image -jar ./target/hello-cli-1.0-SNAPSHOT-jar-with-dependencies.jar hello-cli

3. Result

This native executable is ready to be launched:

$ ./hello-cli -h
Usage: hello-cli [-hV]
Prints a nice hello
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
$ ./hello-cli
Bien le bonjour, humain.

This was so easy!