Trying to run a very simple Spring Boot 3 app on GraalVM (openjdk 19.0.1). The app just stores some data in H2 on startup. It is basically the same as what Josh does in the Spring Tips about Ahead-of-Time compilation, but using Kotlin instead of Java.

When starting the native image, I get the following error after Spring startup:

java.lang.UnsupportedOperationException: Kotlin class com.example.demo.basics.Customer has no .copy(…) method for property id
        at org.springframework.data.mapping.model.BeanWrapper$KotlinCopyUtil.setProperty(BeanWrapper.java:171) ~[na:na]
        at org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:79) ~[na:na]
...

The code which fails is the following class:

@Configuration
class BasicsConfiguration {
    @Bean // execute on application start
    fun basicsApplicationListener(customerRepository: CustomerRepository): ApplicationListener<ApplicationReadyEvent> {
        return ApplicationListener<ApplicationReadyEvent> {
            // store some values in the database
            customerRepository
                .saveAll(listOf("A", "B", "C").map { Customer(null, it) })
                .forEach { println(it) }
        }
    }
}

interface CustomerRepository : CrudRepository<Customer, Int>

data class Customer(@Id val id: Long?, val name: String)

Running the app on the JDK works perfectly fine: ./gradlew bootRun

2022-11-30T11:23:15.300+01:00  INFO 33997 --- [           main] com.example.demo.DemoApplicationKt       : Started DemoApplicationKt in 2.383 seconds (process running for 2.733)
Customer(id=1, name=A)
Customer(id=2, name=B)
Customer(id=3, name=C)

The native image is also created successfully: ./gradlew nativeCompile

Starting the native image works, the server process starts up but then fails:

2022-11-30T11:08:11.085+01:00  INFO 33059 --- [           main] com.example.demo.DemoApplicationKt       : Started DemoApplicationKt in 0.147 seconds (process running for 0.158)
2022-11-30T11:08:11.089+01:00 ERROR 33059 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.UnsupportedOperationException: Kotlin class com.example.demo.basics.Customer has no .copy(…) method for property id
        at org.springframework.data.mapping.model.BeanWrapper$KotlinCopyUtil.setProperty(BeanWrapper.java:171) ~[na:na]
        at org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:79) ~[na:na]
...

When I add a special reflect-config.json the code runs successfully:

[
  {
    "name": "com.example.demo.basics.Customer",
    "allDeclaredFields": true,
    "queryAllDeclaredMethods": true,
    "queryAllPublicMethods": true,
    "queryAllDeclaredConstructors": true,
    "methods": [
      {
        "name": "<init>",
        "parameterTypes": [
          "java.lang.Long",
          "java.lang.String"
        ]
      },
      {
        "name": "component1",
        "parameterTypes": []
      },
      {
        "name": "component2",
        "parameterTypes": []
      },
      {
        "name": "copy",
        "parameterTypes": [
          "java.lang.Long",
          "java.lang.String"
        ]
      },
      {
        "name": "copy$default",
        "parameterTypes": [
          "com.example.demo.basics.Customer",
          "java.lang.Long",
          "java.lang.String",
          "int",
          "java.lang.Object"
        ]
      },
      {
        "name": "equals",
        "parameterTypes": [
          "java.lang.Object"
        ]
      },
      {
        "name": "hashCode",
        "parameterTypes": []
      },
      {
        "name": "toString",
        "parameterTypes": []
      }
    ]
  }]

Of course I do not want to manually add a reflect config for each data class. Am I missing a config param or is something not fully created?

Repo: https://github.com/HenningWaack/springboot-kotlin-graalvm-demo

Thanks!

Comment From: philwebb

It looks like Spring Data might be missing hints for that code path. I've raised https://github.com/spring-projects/spring-data-commons/issues/2748 so that they can take a look.