Liberica NIK: Building native images from Spring Boot applications

1. Introduction

Spring Boot 3.0.0-M5 includes numerous essential improvements, including the baked-in support for GraalVM Native Image. This document will guide you through generating a native image out of a Java application based on Spring Boot 3.0.

2. Install Liberica NIK

It would be best to utilize a powerful computer with several gigabytes of RAM to work with native images. Opt for a cloud service provided by Amazon or a workstation so as not to overload the laptop. We will be using Linux bash commands further on because bash is a perfect way of accessing the code remotely. macOS commands are similar. As for Windows, you can use any alternative, for instance, bash included in the Git package for Windows.

Download Liberica Native Image Kit for your system. Choose a Full version for our purposes.

Unpack tar.gz with the following command:

tar -xzvf ./bellsoft-liberica.tar.gz

Check that Liberica NIK is installed:

java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode, sharing)

You can then use Maven commands with the JAVA_HOME= prefix.

If you get the error "java: No such file or directory" on Linux, you installed the binary for Alpine Linux, not Linux. Check the binary carefully.

3. Create a Spring Boot project

The easiest way to create a new Spring Boot project is to generate one with Spring Initializr. Select Java 17, Maven, JAR, and Spring SNAPSHOT-version (3.0.2 at the time of writing this document), then fill in the fields for project metadata. We don’t need any dependencies.

Build the project and verify that everything is working:

time java -jar ./target/native-image-demo-0.0.1-SNAPSHOT.jar

real	0m1.404s
user	0m4.883s
sys	    0m0.169s

It takes only a second for Spring to start up, but we can do even better with GraalVM Native Image.

Let’s build the project with the following command:

JAVA_HOME= ./mvnw -Pnative native:compile

The resulting native image is in the target directory.

Check how fast the native image starts up:

time /home/username/test/native-image-demo/target/native-image-demo

real	0m0.026s
user	0m0.013s
sys	0m0.013s

The startup is several times faster than with a standard Spring JAR.