Version: 3.2.0-M1 (also 3.1.2) (Kotlin 1.9.0)
To reproduce: https://github.com/rkudryashov/sb-repro
Stacktrace:
sb-repro | 07:32:23.317 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed
sb-repro | java.lang.IllegalArgumentException: Could not find class [com.romankudryashov.sbrepro.SbReproKt__ApplicationContextInitializer]
sb-repro | at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:348)
sb-repro | at org.springframework.context.aot.AotApplicationContextInitializer.instantiateInitializer(AotApplicationContextInitializer.java:80)
sb-repro | at org.springframework.context.aot.AotApplicationContextInitializer.initialize(AotApplicationContextInitializer.java:71)
sb-repro | at org.springframework.context.aot.AotApplicationContextInitializer.lambda$forInitializerClasses$0(AotApplicationContextInitializer.java:61)
sb-repro | at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:607)
sb-repro | at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:387)
sb-repro | at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
sb-repro | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
sb-repro | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
sb-repro | at com.romankudryashov.sbrepro.SbReproKt.main(SbRepro.kt:28)
sb-repro | Caused by: java.lang.ClassNotFoundException: com.romankudryashov.sbrepro.SbReproKt__ApplicationContextInitializer
sb-repro | at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:123)
sb-repro | at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:87)
sb-repro | at java.base@17.0.7/java.lang.Class.forName(DynamicHub.java:1324)
sb-repro | at java.base@17.0.7/java.lang.Class.forName(DynamicHub.java:1313)
sb-repro | at org.springframework.util.ClassUtils.forName(ClassUtils.java:298)
sb-repro | at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:338)
sb-repro | ... 9 common frames omitted
There is no such error when using 1.8.22 version of Kotlin.
Comment From: mhalbritter
It looks like that Spring Boot with Kotlin 1.9.0 is broken with native compilation.
A empty project created by start.spring.io fails to compile with:
> Task :nativeCompile FAILED
[native-image-plugin] Quick build environment variable is set.
[native-image-plugin] GraalVM Toolchain detection is disabled
[native-image-plugin] GraalVM location read from environment variable: JAVA_HOME
[native-image-plugin] Native Image executable path: /Users/mkammerer/.sdkman/candidates/java/17.0.7-graal/lib/svm/bin/native-image
Error: Please specify class (or <module>/<mainclass>) containing the main entry point method. (see --help)
It works with Kotlin 1.8.22.
Comment From: mhalbritter
That's weird. native-image complains that the main entry point is not specified. in build/generated/aotResources/META-INF/native-image/com.example/kotlin-native-test/native-image.properties it points to the main class, and the main class is there in build/classes/kotlin/main/com/example/kotlinnativetest/KotlinNativeTestApplicationKt.class.
When copying the native-image.properties into my src/main/resources/META-INF/native-image folder, the compile works. But running it gives me:
10:01:59.056 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed
java.lang.IllegalArgumentException: Could not find class [com.example.kotlinnativetest.KotlinNativeTestApplicationKt__ApplicationContextInitializer]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:348)
at org.springframework.context.aot.AotApplicationContextInitializer.instantiateInitializer(AotApplicationContextInitializer.java:80)
at org.springframework.context.aot.AotApplicationContextInitializer.initialize(AotApplicationContextInitializer.java:71)
at org.springframework.context.aot.AotApplicationContextInitializer.lambda$forInitializerClasses$0(AotApplicationContextInitializer.java:61)
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:607)
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:387)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at com.example.kotlinnativetest.KotlinNativeTestApplicationKt.main(KotlinNativeTestApplication.kt:13)
Caused by: java.lang.ClassNotFoundException: com.example.kotlinnativetest.KotlinNativeTestApplicationKt__ApplicationContextInitializer
at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:123)
at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:87)
at java.base@17.0.7/java.lang.Class.forName(DynamicHub.java:1322)
at java.base@17.0.7/java.lang.Class.forName(DynamicHub.java:1311)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:298)
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:338)
... 9 common frames omitted
But this class is there, too: build/classes/java/aot/com/example/kotlinnativetest/KotlinNativeTestApplicationKt__ApplicationContextInitializer.class.
It looks like some classpath issue?
Comment From: mhalbritter
It's a Gradle issue. The same project with Maven works fine.
Comment From: wilkinsona
Kotlin 1.9.0 appears to break the configuration of our aot source set. Specifically, the resources generated by AOT processing are not in sourceSets.aot.resources.srcDirs. With Kotlin 1.8.22 the src dirs are src/aot/resources and build/generated/aotResources. With Kotlin 1.9.0 it's only src/out/resources.
It looks like applying Kotlin's plugin resets the src dirs to their defaults. If the plugin application order is changed such that the AOT source set is created after the Kotlin plugins are applied, the problem does not occur.
plugins {
id("java")
id("org.springframework.boot")
id("io.spring.dependency-management")
id("org.hibernate.orm")
kotlin("jvm")
kotlin("plugin.spring")
kotlin("plugin.jpa")
id("org.graalvm.buildtools.native")
}
With the plugin ordering above, nativeCompile succeeds for the supplied sample.
Comment From: wilkinsona
Here's a minimal reproducer:
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.9.0' apply false
}
println sourceSets.main.resources.srcDirs
sourceSets.main.resources.srcDir "src/main/extra-resources"
println sourceSets.main.resources.srcDirs
apply plugin: 'org.jetbrains.kotlin.jvm'
println sourceSets.main.resources.srcDirs
$ gradle
> Configure project :
[/Users/awilkinson/dev/temp/kotlin-resource-dirs-problem/src/main/resources]
[/Users/awilkinson/dev/temp/kotlin-resource-dirs-problem/src/main/resources, /Users/awilkinson/dev/temp/kotlin-resource-dirs-problem/src/main/extra-resources]
[/Users/awilkinson/dev/temp/kotlin-resource-dirs-problem/src/main/resources]
Applying org.jetbrains.kotlin.jvm has removed src/main/extra-resources. This does not happen with 1.8.22.
I've contacted JetBrains about the apparent regression. I'll update here when I hear back from them.
Comment From: rkudryashov
With the plugin ordering above, nativeCompile succeeds for the supplied sample.
Confirm, this commit fixes the issue
Comment From: wilkinsona
JetBrains have confirmed that there's a problem in Kotlin's Gradle plugin. It's being tracked by KT-60459. I'm going to close this issue in favor of it.
Until a fix is available in Kotlin's Gradle plugin the problem can be worked around by applying it first. I've added a note about this in a couple of places on the wiki:
- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-with-GraalVM#kotlin
- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2.0-M1-Release-Notes#kotlin-190-and-gradle