mill icon indicating copy to clipboard operation
mill copied to clipboard

Spring boot AOT mode fails with Kotlin

Open re-thc opened this issue 3 weeks ago • 13 comments

Hi, just tested 1.1.0-RC3 with the new SpringBootModule. Thanks for adding it. Using the "optimized" AOT mode fails with Kotlin. It works with Java.

[error] out/test/springBootProcessAOT.dest/sources/com/test/App__BeanDefinitions.java:16:64 ^ cannot find symbol symbol: class App location: class com.test.App__BeanDefinitions

re-thc avatar Dec 04 '25 04:12 re-thc

Thanks for reporting, I'll take a look today, could you also share a sample of your build.mill configuration? Or if you have a complete example even better, I can add it in the collection

vaslabs avatar Dec 04 '25 07:12 vaslabs

@vaslabs Probably related: https://github.com/com-lihaoyi/mill/pull/6168#issuecomment-3528129611 (If this involves annotation processors)

lefou avatar Dec 04 '25 09:12 lefou

@vaslabs Probably related: #6168 (comment) (If this involves annotation processors)

thanks, yes, I've just started working on it! EDIT: (I mean not sure it's the annotation processors, I'll know soon)

vaslabs avatar Dec 04 '25 09:12 vaslabs

I suspect it's the directory structure (e.g. need to use KotlinMavenModule), I'm preparing a PR with this working example:

package build

import mill.*
import mill.javalib.*
import mill.javalib.spring.boot.SpringBootModule
import mill.javalib.TestModule.{Junit4, Junit5}
import mill.javalib.publish.*
import mill.kotlinlib.KotlinMavenModule

object `package` extends SpringBootModule, KotlinMavenModule { outer =>

  override def springBootPlatformVersion = "3.5.7"

  override def kotlinVersion = "2.2.21"
  override def artifactName: T[String] = "spring-boot-native-demo"

  override def kotlincOptions: T[Seq[String]] = super.kotlincOptions() ++ Seq("-jvm-target", "17")

  override def mvnDeps = Seq(
    mvn"com.fasterxml.jackson.module:jackson-module-kotlin:2.19.2",
    mvn"org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion()}",
    mvn"org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion()}",
    mvn"org.springframework.boot:spring-boot-starter-web"
  )

  object prod extends SpringBootOptimisedBuildModule, KotlinMavenModule {
    override def kotlinVersion = outer.kotlinVersion()
    override def kotlincOptions = outer.kotlincOptions()
  }

  object native extends KotlinMavenModule, NativeSpringBootBuildModule {
    override def kotlinVersion = outer.kotlinVersion()
    override def kotlincOptions = outer.kotlincOptions()
    def jvmId = "graalvm-community:23.0.1"
  }
}

vaslabs avatar Dec 04 '25 10:12 vaslabs

PR with working example: https://github.com/com-lihaoyi/mill/pull/6315

@re-thc could you check if this is the issue? otherwise, I'll need some guidance to reproduce it

vaslabs avatar Dec 04 '25 10:12 vaslabs

Ok. Please make sure your PR answers the question where the need to use KotlinMavenModule comes from. Is it required due to technical limitations, or just because the source directories use the Maven layout?

lefou avatar Dec 04 '25 10:12 lefou

Ok. Please make sure your PR answers the question where the need to use KotlinMavenModule comes from. Is it required due to technical limitations, or just because the source directories use the Maven layout?

I suspect the layout might be needing it, I did have a similar issue when not extending the MavenModule for Java

vaslabs avatar Dec 04 '25 10:12 vaslabs

I think we should ultimately try to fix the underlying problem. Mill allows users to configure all inputs, so we should explicitly state modules, that don't support that or require some specific layouts.

And we should open tickets to the integrated frameworks/tools, to get those limitations fixed upstream.

lefou avatar Dec 04 '25 10:12 lefou

I think we should ultimately try to fix the underlying problem. Mill allows users to configure all inputs, so we should explicitly state modules, that don't support that or require some specific layouts.

And we should open tickets to the integrated frameworks/tools, to get those limitations fixed upstream.

it's not the AOT that requires the layout, the AOT was processed fine. But because the compilation looks for the sources in a different directory than MavenModule and co, the generated code was referencing sources that could not be found (this is my suspicion, without knowing @re-thc's initial source layout)

basically I suspect that either the layout was different or MavenModule was used instead of KotlinMavenModule so the kotlin directory was out:

  private def sources0 = Task.Sources("src/main/kotlin")
  override def sources = super.sources() ++ sources0()

vaslabs avatar Dec 04 '25 10:12 vaslabs

i.e. if I change the layout, it works with KotlinModule

Image

vaslabs avatar Dec 04 '25 10:12 vaslabs

I used the default. No MavenModule.

re-thc avatar Dec 04 '25 10:12 re-thc

I used the default. No MavenModule.

could you share a bit more about your setup? or do my comments and example help in resolving the issue in either case (source layout difference)?

vaslabs avatar Dec 04 '25 10:12 vaslabs

found some runtime issues anyway (with native), so I'm looking into them too

vaslabs avatar Dec 04 '25 10:12 vaslabs