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;

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

  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);

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


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!