Issue Description
When using Spring Boot 3.x with GraalVM native compilation, I have two classes:
class RSocketFeignRuntimeHints : RuntimeHintsRegistrar {
override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
// Register hints for RSocket Feign classes
}
}
class RSocketClientsRegistrar : ImportBeanDefinitionRegistrar {
override fun registerBeanDefinitions(metadata: AnnotationMetadata, registry: BeanDefinitionRegistry) {
// Register RSocket client beans
}
}
Expected Behavior
During native compilation:
1. RuntimeHintsRegistrar
should be executed first to register necessary hints
2. Then ImportBeanDefinitionRegistrar
should be executed to register beans
Actual Behavior
When running ./gradlew nativeCompile
:
1. ImportBeanDefinitionRegistrar
is executed first
2. The compilation fails because necessary hints are not registered
3. RuntimeHintsRegistrar
is not executed at all
Configuration
# src/main/resources/META-INF/spring/org.springframework.aot.hint.RuntimeHintsRegistrar
org.fu.common.feign.model.RSocketFeignRuntimeHints
# src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
org.fu.common.feign.RSocketClientsRegistrar
Question
How can we ensure RuntimeHintsRegistrar
is executed before ImportBeanDefinitionRegistrar
during native compilation?
Environment
- Spring Boot: 3.3.5
- GraalVM CE: 21.0.2
- Gradle: 8.5
This seems to be a timing issue in Spring's AOT processing pipeline. Any suggestions on how to control the execution order would be appreciated.
Comment From: bclozel
Have you seen the AOT section in the reference documentation? Maybe using a BeanFactoryInitializationAotProcessor instead of a runtime hints registrar is a better fit.
Comment From: yuri-li
Thank you, I tried BeanDefinitionRegistryPostProcessor, the source code is as follows:
@ConditionalOnClass(RSocketRequester::class)
class RSocketClientsRegistrar : BeanDefinitionRegistryPostProcessor, PriorityOrdered, EnvironmentAware {
override fun getOrder() = Ordered.HIGHEST_PRECEDENCE
override fun setEnvironment(environment: Environment) {
this._environment = environment
}
private val log = LoggerFactory.getLogger(this::class.java)
private lateinit var _environment: Environment
override fun postProcessBeanDefinitionRegistry(registry: BeanDefinitionRegistry) {
log.info("start loading RSocketClientsRegistrar")
//others
}
}
}
The problem is not solved.
In addition, the current project is a basic project similar to apache open feign. I think other spring boot projects can automatically load related configurations after getting dependencies, so the following configuration is used as follows:
src/main/resources/
└── META-INF
└── spring
└── org.springframework.aot.hint.RuntimeHintsRegistrar
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
Comment From: bclozel
I'm not sure what's the context or use case here, but I believe I've pointed you to the right direction. The section in the docs says it all and Spring Framework has several implementations of this pattern for AOT support.
I think you should ask a question on StackOverflow and better explain what you're trying to do and what you mean by the problem is not solve.