I've just upgraded several projects to Java 19, Spring Boot 3.0.2, Kotlin 1.8.0 with Maven and I'd like Spring Boot to generate native images.
<java.version>19</java.version>
<kotlin.version>1.8.0</kotlin.version>
The relevant part of the configuration of spring-boot-maven-plugin
is:
<configuration>
<image>
<env>
<BP_JVM_VERSION>19.*</BP_JVM_VERSION>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+HeapDumpOnOutOfMemoryError -XX:MaxDirectMemorySize=64M</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
</env>
</image>
</configuration>
However, when I build one of the projects with
mvn -Pnative spring-boot:build-image
then the build fails with the following error message:
[INFO] [creator] Paketo Buildpack for BellSoft Liberica 9.10.2
[INFO] [creator] unable to find dependency
[INFO] [creator] no valid dependencies for native-image-svm, 19.*, and io.paketo.stacks.tiny in [(jdk, 8.0.362, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jre, 8.0.362, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jdk, 11.0.18, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jre, 11.0.18, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (native-image-svm, 11.0.17, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jdk, 17.0.6, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jre, 17.0.6, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (native-image-svm, 17.0.5, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jdk, 19.0.2, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *]) (jre, 19.0.2, [io.buildpacks.stacks.bionic io.paketo.stacks.tiny *])]
[INFO] [creator] ERROR: failed to build: exit status 1
What's missing?
Update: When I downgrade to Java 17 with Kotlin 1.7.21, then the build succeeds and apparently there's no support yet in the Liberica Native Image Kit for Java 19. https://bell-sw.com/pages/downloads/native-image-kit/#/nik-22-19
Let me provide you with alternatives to downgrading your Java version (in case you e.g. want to use virtual threads).
You might be successful using GraalVM instead of Liberica NIK. You can configure this in your pom.xml
as described in the section Use an alternative native image toolkit
of the Spring Boot Documentation:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<buildpacks>
<buildpack>gcr.io/paketo-buildpacks/graalvm</buildpack>
<buildpack>gcr.io/paketo-buildpacks/java-native-image</buildpack>
</buildpacks>
</image>
</configuration>
</plugin>
Since The GraalVM Buildpack supports Java 19, you should be able to use it:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<buildpacks>
<buildpack>gcr.io/paketo-buildpacks/graalvm</buildpack>
<buildpack>gcr.io/paketo-buildpacks/java-native-image</buildpack>
</buildpacks>
<env>
<BP_JVM_VERSION>19.0.1</BP_JVM_VERSION>
</env>
</image>
</configuration>
</plugin>
As an alternative, it would be possible to not use buildpacks for creating the native image but instead create a native executable using mvn -Pnative package
(or mvn -Pnative native:compile
) See Getting started with Native Build Tools.
Then, you could create your own docker image (e.g. using a Dockerfile
or similar) and include that.