I have problems with Springs new KotlinDSL beans c...
# getting-started
s
I have problems with Springs new KotlinDSL beans configuration. I have this minimal project where a class configuration approach (on the "main"-branch) works:
Copy code
@SpringBootApplication
class HelloApp

fun main() {
    runApplication<HelloApp>()
}

@Configuration
class Config {
    @Bean fun getServer(
        bus: Bus,
        helloService: HelloService,
    ): Server = JAXRSServerFactoryBean().apply {
        setBus(bus)
        address = "/rs"
        setServiceBeans(listOf(helloService))
        setProvider(
            JacksonJsonProvider().apply {
                setMapper(jacksonObjectMapper())
            }
        )
    }.create()
}
but the KotlinDSL configuration approach (on the "programatic_config"-branch) using the Kotlin DSL doesn't work:
Copy code
@SpringBootApplication
class HelloApp

fun main() {
    runApplication<HelloApp>() {
        beans {
            bean<Server> {
                JAXRSServerFactoryBean().apply {
                    setBus(ref<Bus>())
                    address = "/rs"
                    setServiceBeans(listOf(ref<HelloService>()))
                    setProvider(
                        JacksonJsonProvider().apply {
                            setMapper(jacksonObjectMapper())
                        }
                    )
                }.create()
            }
        }
    }
}
Working in this context means that after start-up (
./gradlew clean bootRun
) a GET call to http://localhost:8080/services/rs/hello should return {"msg": "hello back"} instead of a 404 which is what I get with the KotlinDSL configuration, and I don't understand what's going wrong. There is a test-requests.http-file in the project to easily call this URL from within IntelliJ. Is this a bug in Spring, or am I missing something?
c
Spring’s functional bean registration (and the dsl layer on top of it) are designed to work with route handlers (‘coRouter’ in the Kotlin dsl). Annotated controllers won’t work without extra plumbing.
i
As far as I remember,
beans
just creates an initializer which must be integrated into the app somehow for actual creation of beans. Probably you need to do
beans { }.initialize(...)
or
addInitializers(beans { })
s
@Ivan Pavlov you're correct! (technically @Chris Lee you were also correct, but Ivan actually told me what the plumbing looks like, so he gets bonus points 😆)
addInitializers(beans { })
works!
beans{...}.initialize(...)
exists but wants an instance of
GenericApplicationContext
and I don't know where to get one from, but one working solution is enough 👍
👍 1