Issue
Running a native compiled image causes an exception that the __ApplicationContextInitializer class could not be found.
Explanation
As I read from https://docs.spring.io/spring-boot/docs/3.0.0/reference/html/native-image.html#native-image.testing.with-native-build-tools.maven it is possible to setup the native build without the Spring Boot parent in the pom.xml. (see hint)
I configured the maven configuration based on the gradle parent build found here: https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle#L231
I changed the builder image to dashaun/java-native-builder-arm64 as this is compatible with arm64 based CPU archs.
Versions and Setup
Spring Boot: 3.0.1 Spring Boot Maven Plugin: 3.0.1 Native Maven Plugin: 0.9.19 Java: 17.0.5
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<spring.version>3.0.1</spring.version>
<native-maven-plugin.version>0.9.19</native-maven-plugin.version>
</properties>
<profiles>
<profile>
<id>native</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.version}</version>
<configuration>
<image>
<builder>dashaun/java-native-builder-arm64</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
<BP_NATIVE_IMAGE_BUILD_ARGUMENTS>-H:+ReportExceptionStackTraces</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
</env>
</image>
</configuration>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-maven-plugin.version}</version>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
<requiredVersion>22.3</requiredVersion>
</configuration>
<executions>
<execution>
<id>add-reachability-metadata</id>
<goals>
<goal>add-reachability-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>nativeTest</id>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.version}</version>
<executions>
<execution>
<id>process-test-aot</id>
<goals>
<goal>process-test-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native-maven-plugin.version}</version>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<metadataRepository>
<enabled>true</enabled>
</metadataRepository>
<requiredVersion>22.3</requiredVersion>
</configuration>
<executions>
<execution>
<id>native-test</id>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
Exception from pod log
2023-01-10 12:18:48
2023-01-10 12:18:48 . ____ _ __ _ _
2023-01-10 12:18:48 /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2023-01-10 12:18:48 ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2023-01-10 12:18:48 \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2023-01-10 12:18:48 ' |____| .__|_| |_|_| |_\__, | / / / /
2023-01-10 12:18:48 =========|_|==============|___/=/_/_/_/
2023-01-10 12:18:48 :: Spring Boot :: (v3.0.1)
2023-01-10 12:18:48
2023-01-10 12:18:48 11:18:48.865 [main] DEBUG org.springframework.context.aot.AotApplicationContextInitializer - Initializing ApplicationContext with AOT
2023-01-10 12:18:48 11:18:48.865 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
2023-01-10 12:18:48 java.lang.IllegalArgumentException: Could not find class [client.ClientCredentialsApplication__ApplicationContextInitializer]
2023-01-10 12:18:48 at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:333)
2023-01-10 12:18:48 at org.springframework.context.aot.AotApplicationContextInitializer.instantiateInitializer(AotApplicationContextInitializer.java:80)
2023-01-10 12:18:48 at org.springframework.context.aot.AotApplicationContextInitializer.initialize(AotApplicationContextInitializer.java:71)
2023-01-10 12:18:48 at org.springframework.context.aot.AotApplicationContextInitializer.lambda$forInitializerClasses$0(AotApplicationContextInitializer.java:61)
2023-01-10 12:18:48 at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:603)
2023-01-10 12:18:48 at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:383)
2023-01-10 12:18:48 at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
2023-01-10 12:18:48 at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:150)
2023-01-10 12:18:48 at client.ClientCredentialsApplication.main(ClientCredentialsApplication.java:48)
2023-01-10 12:18:48 Caused by: java.lang.ClassNotFoundException: client.ClientCredentialsApplication__ApplicationContextInitializer
2023-01-10 12:18:48 at java.base@17.0.5/java.lang.Class.forName(DynamicHub.java:1132)
2023-01-10 12:18:48 at org.springframework.util.ClassUtils.forName(ClassUtils.java:283)
2023-01-10 12:18:48 at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:323)
2023-01-10 12:18:48 ... 8 common frames omitted
Comment From: klopfdreh
See also: https://github.com/oracle/graal/issues/5683#issuecomment-1377084666
Note: The initial post mixed spring-native experimental with Spring Boot 3, but later on there was a comment with exact the same issue I have.
Comment From: mhalbritter
If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
Comment From: klopfdreh
No problem: vsrc-13725.zip
There are 3 submodules - oauth / server / client - the client is the one you can run the spring native profile with mvn -pl client -am -Pnative spring-boot:build-image - you have also to change the builder to paketobuildpacks/builder:tiny if not running om arm64
Comment From: mhalbritter
It looks like you have configured the pluginManagement for the boot and the NBT plugin, but not the plugin for the build itself. If you add this, it should work:
<build>
// ...
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
</plugins>
// ...
You can now see the process-aot mojo running in the maven logs, which creates the __ApplicationContextInitializer classes.
Comment From: klopfdreh
Thanks a lot!
Comment From: wghdir
select native in profiles,and remake you native image