diff --git a/core/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/core/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index c38474584f6..661edccbe3e 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -419,9 +419,6 @@ public class SpringApplication { } private void addAotGeneratedInitializerIfNecessary(List> initializers) { - if (NativeDetector.inNativeImage()) { - NativeImageRequirementsException.throwIfNotMet(); - } if (AotDetector.useGeneratedArtifacts()) { List> aotInitializers = new ArrayList<>( initializers.stream().filter(AotApplicationContextInitializer.class::isInstance).toList()); @@ -436,6 +433,9 @@ public class SpringApplication { initializers.removeAll(aotInitializers); initializers.addAll(0, aotInitializers); } + if (NativeDetector.inNativeImage()) { + NativeImageRequirementsException.throwIfNotMet(); + } } private void refreshContext(ConfigurableApplicationContext context) { diff --git a/core/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/core/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index 08216f19677..a6d80f3f159 100644 --- a/core/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/core/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -77,7 +77,6 @@ import org.springframework.boot.context.event.ApplicationStartingEvent; import org.springframework.boot.context.event.SpringApplicationEvent; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.env.DefaultPropertiesPropertySource; -import org.springframework.boot.system.JavaVersion; import org.springframework.boot.testsupport.classpath.ForkedClassPath; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.testsupport.system.CapturedOutput; @@ -756,14 +755,32 @@ class SpringApplicationTests { application.setWebApplicationType(WebApplicationType.NONE); assertThatExceptionOfType(NativeImageRequirementsException.class).isThrownBy(application::run) .withMessage("Native Image requirements not met. " - + "Native Image must support at least Java 25 but Java %s was detected" - .formatted(JavaVersion.getJavaVersion())); + + "Native Image must support at least Java 25 but Java %d was detected" + .formatted(Runtime.version().feature())); } finally { System.clearProperty("org.graalvm.nativeimage.imagecode"); } } + @Test + @ForkedClassPath + @EnabledForJreRange(max = JRE.JAVA_24) + void missingAotInitializerTakesPrecedenceOverNativeImageRequirementsCheck() { + System.setProperty("spring.aot.enabled", "true"); + System.setProperty("org.graalvm.nativeimage.imagecode", "true"); + try { + SpringApplication application = new SpringApplication(); + application.setWebApplicationType(WebApplicationType.NONE); + assertThatExceptionOfType(AotInitializerNotFoundException.class).isThrownBy(application::run) + .withMessageStartingWith("Startup with AOT mode enabled failed"); + } + finally { + System.clearProperty("org.graalvm.nativeimage.imagecode"); + System.clearProperty("spring.aot.enabled"); + } + } + @Test @ForkedClassPath @EnabledForJreRange(min = JRE.JAVA_25)