kotlinVersion = "1.3.21" springBootVersion = '2.1.3.RELEASE'
Following code throws an exception breaking context setup:
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.SpringBootConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.ComponentScan
import org.springframework.stereotype.Component
@SpringBootConfiguration
@ComponentScan
class MyConfig{
@Component
inner class BeanB {
fun print() {
println("beanB")
}
}
}
@SpringBootTest
class KotlinTest {
@Autowired
lateinit var beanB: MyConfig.BeanB
@Test
fun a() {
beanB.print()
}
}
The error is:
Error creating bean with name kotlin.MyConfig$BeanB'
...
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:705)
When translating and running the snippet on Java everything works as expected.
Comment From: anton-kapelyushok
Found an issue in spring-framework repo https://github.com/spring-projects/spring-framework/issues/21755 When it will be released?
Comment From: sdeleuze
I think you need to differentiate nested and inner classes. Nested classes are expected to be supported, inner classes are not since the need a reference on the outer class which is not something that would make sense in that case IMO.
So if we do something here, I think that would be mainly improving the Exception to provide a better error message.
Could you check with nested class and send me a feedback?
Inner classes are not supported because they need a reference on
Comment From: anton-kapelyushok
I think you need to differentiate nested and inner classes
Let's be clear here: nested class is a class defined inside a class having no modifier in kotlin and static modifier in java inner class is a class defined inside a class having inner modifier in kotlin and no modifier in java
I am talking about inner classes in the issue. Nested classes work as expected in kotlin.
inner classes are not since the need a reference on the outer class which is not something that would make sense in that case IMO.
I cannot agree here.
Suppose we have java configuration
@Configuration
public class MyConfig {
@Component
public class MyComponent {
}
}
and configuration translated directly to kotlin
@Configuration
open class MyConfig {
@Component
open inner class MyComponent
}
Java version works completely fine when kotlin one fails with exception. It is expected that both configurations would work exactly the same, since nothing has changed when translating from java to kotlin.
Also there is no issue when we inject config to the component explicitly, following configuration works fine
@Configuration
open class MyConfig
@Component
open class MyComponent(val myConfig: MyConfig)
So I don't see why inner classes should not work
If we talk about practical use here, this type of configuration could be useful when we are defining several components using one shared dependency and we don't want to inject it to each of them separately.
Comment From: sdeleuze
Hi, sorry for the delay. Can't reproduce anymore with Spring Framework 6.0.4 so I guess it has been fixed since.