Take the following kotlin @Service
:
@Service
class Service(
private val applicationContext: ApplicationContext,
private val client: Client = Client()
)
When running on JVM the code behaves as expected: only the constructor parameter without a default value is autowired. When running the native image the application does not start and throws the following exception indicating that spring attempts to autowire all constructor parameters (even the one with a default value):
java.lang.NullPointerException: Parameter specified as non-null is null: method de.darkatra.kotlindiissue.Service.<init>, parameter client
Reproducer with details: https://github.com/DarkAtra/spring-native-kotlin-di-issue
Affected Spring Framework versions: 6.0.2
, 6.0.3
, 6.0.4
(verified by building the current spring-boot main branch locally)
Comment From: sdeleuze
Tricky one!
In Kotlin interoperability documentation, we can read:
Normally, if you write a Kotlin function with default parameter values, it will be visible in Java only as a full signature, with all parameters present. If you wish to expose multiple overloads to Java callers, you can use the @JvmOverloads annotation.
So I think our best (only ?) chance is to invoke BeanUtils#instantiateClass(java.lang.reflect.Constructor<T>, java.lang.Object...)
and add invoke hint for the constructor for Kotlin constructors with default values.
Comment From: sdeleuze
Regrouping default parameter value in Spring Framework 6.1 along to #21139.