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