spring framework 6.0.2 (spring boot 3.0.0) , graalvm 22.3.0 (java 17.0.5)
routes dsl definition
fun routes(employeeHandler: EmployeeHandler, attendanceHandler: AttendanceHandler) = coRouter {
"$APPLICATION_BASE_URL/employee".nest {
GET("", employeeHandler::findAll)
GET("/{id}", employeeHandler::find)
POST("/save", employeeHandler::save)
"/delete".nest {
DELETE("", employeeHandler::deleteAll)
DELETE("/{id}", employeeHandler::delete)
}
}
"$APPLICATION_BASE_URL/login".nest {
GET("", attendanceHandler::findAll)
GET("/{deviceId}", attendanceHandler::findByEmployee)
POST("/save", attendanceHandler::save)
"/delete".nest {
DELETE("", attendanceHandler::deleteAll)
DELETE("/query", attendanceHandler::deleteByMonthAndYear)
DELETE("/{deviceId}", attendanceHandler::deleteByEmployee)
}
}
}
spring main application
@SpringBootApplication
class AttendanceMainApp
fun main() {
runApplication<AttendanceMainApp> {
addInitializers(
beans {
bean<EmployeeService>()
bean<EmployeeHandler>()
bean<AttendanceService>()
bean<AttendanceHandler>()
bean(::routes)
}
)
}
}
when launch gradle task: gradle nativeCompile an exception appear
2022-12-07T10:18:49.792+01:00 INFO 166674 --- [ main] dev.attendance.AttendanceMainAppKt : Starting AttendanceMainAppKt using Java 17.0.5 with PID 166674 (/home/halim/Desktop/attendance-service/build/classes/kotlin/main started by halim in /home/halim/Desktop/attendance-service)
2022-12-07T10:18:49.796+01:00 INFO 166674 --- [ main] dev.attendance.AttendanceMainAppKt : No active profile set, falling back to 1 default profile: "default"
2022-12-07T10:18:50.548+01:00 INFO 166674 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Reactive MongoDB repositories in DEFAULT mode.
2022-12-07T10:18:50.580+01:00 INFO 166674 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 0 Reactive MongoDB repository interfaces.
Exception in thread "main" java.lang.IllegalStateException: No constructor or factory method candidate found for Root bean: class [org.springframework.web.reactive.function.server.RouterFunction]; scope=singleton; abstract=false; lazyInit=true; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null and argument types []
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorOrFactoryMethod(ConstructorResolver.java:939)
at org.springframework.beans.factory.support.RegisteredBean.resolveConstructorOrFactoryMethod(RegisteredBean.java:197)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.<init>(BeanDefinitionMethodGenerator.java:79)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:102)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:118)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:45)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:35)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.getContributions(BeanFactoryInitializationAotContributions.java:67)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:49)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:44)
at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
at org.springframework.context.aot.ContextAotProcessor.performAotProcessing(ContextAotProcessor.java:106)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:84)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:49)
at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:76)
whats wrong !!!
Comment From: bclozel
Could you share a minimal sample application that reproduces the problem? Ideally, an application created from start.spring.io and shared as a git repository or a zip file. Thanks!
Comment From: Kotlin-GDE
this is the link of ATENDANCE-SERVICE
https://github.com/halimpuckjava/attendance-service.git
Comment From: scottfrederick
This sample can be simplified significantly and still reproduce the problem.
-
Create a new project from start.spring.io using these options: https://start.spring.io/#!type=gradle-project-kotlin&language=kotlin&platformVersion=3.0.0&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=native,webflux
-
Add
src/main/kotlin/com/example/demo/Routes.kt
that looks like this:
package com.example.demo
import org.springframework.web.reactive.function.server.coRouter
fun routes() = coRouter {
}
- Modify
main
inDemoApplication.kt
to look like this:
fun main(args: Array<String>) {
runApplication<DemoApplication> {
addInitializers(
beans {
bean(::routes)
}
)
}
}
Running ./gradlew nativeCompile
give the same error as above.
Comment From: scottfrederick
@halimpuckjava As a work-around, this change to main
in your sample allows ./gradle nativeCompile
to succeed:
fun main() {
runApplication<AttendanceMainApp> {
addInitializers(
beans {
bean<EmployeeService>()
bean<EmployeeHandler>()
bean<AttendanceService>()
bean<AttendanceHandler>()
}
)
}
}
@Configuration
class RouterConfiguration {
@Bean
fun router() = ::routes
}
Comment From: Kotlin-GDE
thanks, i will try it and give you a feed back
Comment From: sdeleuze
This issue is a duplicate of #29555.