spring-bootmavengraalvmgraalvm-native-imagepreview-feature

SpringBoot3 GraalVM native image - issue building preview feature


I have a SpringBoot app with some JDK preview features.

I hope to build a GraalVM native image out of the project.

To do so, I tried this code:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <env>
                            <BP_JVM_VERSION>23</BP_JVM_VERSION>
                        </env>
                    </image>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>23</source>
                    <target>23</target>
                    <compilerArgs>--enable-preview</compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

and the command mvn -Pnative spring-boot:build-image

This would always fail with

[INFO] --- spring-boot:3.5.0-M1:process-aot (process-aot) @ myproject ---

Exception in thread "main" org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class

at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
    at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:80)
Caused by: java.lang.UnsupportedClassVersionError: Preview features are not enabled for com/service/MyService (class file version 67.65535). Try running with '--enable-preview'
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1026)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:578)
    at java.base/java.lang.Class.forName(Class.java:557)
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:321)
    at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:503)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1620)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1545)

Question:

What maven command, or what should I add in the pom to build a GraalVM native image with preview features?


Solution

  • I also had to set

    <BP_NATIVE_IMAGE_BUILD_ARGUMENTS>--enable-preview</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
    

    for the spring-boot-maven-plugin.

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>24</source>
            <target>24</target>
            <compilerArgs>
              <arg>--enable-preview</arg>
            </compilerArgs>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.graalvm.buildtools</groupId>
          <artifactId>native-maven-plugin</artifactId>
        </plugin>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <configuration>
            <jvmArguments>--enable-preview</jvmArguments>
            <compilerArguments>--enable-preview</compilerArguments>
            <image>
              <env>
                <BP_NATIVE_IMAGE_BUILD_ARGUMENTS>--enable-preview</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
              </env>
            </image>
          </configuration>
        </plugin>
      </plugins>
    </build>