GraalVM demos: AOT compilation of a Java / Kotlin application

This is an example of a GraalVM demo application that shows ahead-of-time compilation of Java and Kotlin code.

Prerequisites

Preparation

Download or clone the repository and navigate into the java-kotlin-aot directory:

git clone https://github.com/graalvm/graalvm-demos
cd graalvm-demos/java-kotlin-aot

This is a simple Java / Kotlin application showing how easy it is to interop between JVM-based languages. A Java method accesses a String from Kotlin and calls a Kotlin function, which later accesses a String from a Java class. Before running this example, you need to build the application.

Note that you can use any JDK for building the application, however we refer to javac from GraalVM in the build script to simplify the prerequisites and not to depend on another JDK installed.

Export the GraalVM home directory as the $GRAALVM_HOME and add $GRAALVM_HOME/bin to the path, using a command-line shell for Linux:

export GRAALVM_HOME=/home/${current_user}/path/to/graalvm

and for Mac OS:

export GRAALVM_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home

Note that your paths are likely to be different depending on the download location.

Then execute:

./build.sh

Have a look at the build.sh script which creates a native image from the Java class. The native-image utility is a part of GraalVM. It is used to compile applications ahead-of-time for faster starup and lower general overhead at runtime.

$GRAALVM_HOME/bin/native-image -cp ./target/mixed-code-hello-world-1.0-SNAPSHOT.jar -H:Name=helloworld -H:Class=hello.JavaHello -H:+ReportUnsupportedElementsAtRuntime

It takes a couple of parameters, the classpath, the main class of the application with -H:Class=... and the name of the resulting executable with -H:Name=....

After executing the native-image command, check the directory, it should have produced an executable file helloworld.

Running the application

To run the application, you need to execute the fat jar file in the target dir. You can run it as a normal Java application using java. Or, since we have a native image prepared, you can run that directly. The run.sh file executes both, and times them with the time utility.

java -cp ./target/mixed-code-hello-world-1.0-SNAPSHOT-jar-with-dependencies.jar hello.JavaHello
./helloworld

Approximately, the following output should be produced:

→ ./run.sh
+ java -cp ./target/mixed-code-hello-world-1.0-SNAPSHOT-jar-with-dependencies.jar hello.JavaHello
Hello from Kotlin!
Hello from Java!

real	0m0.129s
user	0m0.094s
sys	0m0.034s
+ ./helloworld
Hello from Kotlin!
Hello from Java!

real	0m0.010s
user	0m0.003s
sys	0m0.004s

The performance gain of the native version is largely due to the faster startup.

License

The sample application in this directory is taken from the JetBrains Kotlin-examples repository. It is distributed under the Apache License 2.0.