spring-projects/spring-framework · error · AotBeanProcessingException
no suitable constructor or factory method found
Error message
no suitable constructor or factory method found
What it means
Thrown as an AotBeanProcessingException 'no suitable constructor or factory method found' when InstanceSupplierCodeGenerator.generateCode is given an InstantiationDescriptor whose executable is neither a Constructor nor a non-Kotlin-suspending Method. The code generator only knows how to emit code for those two shapes; anything else (a Kotlin suspending function, or a future Executable subclass) is rejected.
Solutions
- If the bean uses Kotlin, ensure kotlin-reflect and a Spring version with coroutine AOT support are present, and avoid marking the bean factory method 'suspend'.
- Refactor the factory method to a non-suspending method or a plain constructor so the code generator can emit code for it.
- Update Spring Framework to a version whose InstanceSupplierCodeGenerator supports the executable shape you are using.
- Register the bean differently (constructor injection, or a non-suspending @Bean method that bridges the coroutine internally).
- Exclude the bean from AOT if the coroutine nature is essential and no AOT path exists yet.
Example fix
// before: Kotlin suspending factory method the code generator rejects
@Bean
suspend fun myBean(): MyBean = ... // suspending
// after: non-suspending factory method
@Bean
fun myBean(): MyBean = runBlocking { ... } Defensive patterns
Strategy: validation
Validate before calling
Executable e = instantiationDescriptor.executable();
boolean supported = e instanceof Constructor<?> ||
(e instanceof Method m && !KotlinDetector.isSuspendingFunction(m));
if (!supported) {
throw new IllegalStateException("Cannot AOT-generate supplier for executable: " + e);
} Type guard
boolean codegenSupported =
(executable instanceof Constructor<?>) ||
(executable instanceof Method m && !KotlinDetector.isSuspendingFunction(m)); Prevention
- Avoid 'suspend' on @Bean factory methods when targeting native image.
- Keep kotlin-reflect and a Spring version with coroutine AOT support in sync.
- Use plain constructors or non-suspending factory methods for AOT beans.
- Test AOT generation in CI for Kotlin beans.
When it happens
Trigger: Calling InstanceSupplierCodeGenerator.generateCode(registeredBean, descriptor) where descriptor.executable() is a Kotlin suspending method, or some non-Constructor/non-(plain Method) Executable. Reached during AOT generation of the instance supplier for a bean whose resolved instantiation executable is not supported.
Common situations: Bean whose factory method is a Kotlin suspending function (coroutine); custom InstantiationDescriptor built programmatically with an unsupported executable; mismatch between Kotlin coroutines support and Spring version; bean factory method that returns a coroutine Publisher/Flow not handled by the codegen path in this Spring version.
Related errors
- Cannot invoke instance method without factoryBeanName:
- Argument type mismatch: expected '
- failed to generate code for bean definition
- Failed to instantiate method
- Failed to load Class [
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/7d97f51ff4d798c9.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java:150
}
/**
* Generate the instance supplier code.
* @param registeredBean the bean to handle
* @param instantiationDescriptor the executable to use to create the bean
* @return the generated code
* @since 6.1.7
*/
public CodeBlock generateCode(RegisteredBean registeredBean, InstantiationDescriptor instantiationDescriptor) {
Executable constructorOrFactoryMethod = instantiationDescriptor.executable();
registerRuntimeHintsIfNecessary(registeredBean, constructorOrFactoryMethod);
if (constructorOrFactoryMethod instanceof Constructor<?> constructor) {
return generateCodeForConstructor(registeredBean, constructor);
}
if (constructorOrFactoryMethod instanceof Method method && !KotlinDetector.isSuspendingFunction(method)) {
return generateCodeForFactoryMethod(registeredBean, method, instantiationDescriptor.targetClass());
}
throw new AotBeanProcessingException(registeredBean, "no suitable constructor or factory method found");
}
private void registerRuntimeHintsIfNecessary(RegisteredBean registeredBean, Executable constructorOrFactoryMethod) {
if (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf) {
RuntimeHints runtimeHints = this.generationContext.getRuntimeHints();
ProxyRuntimeHintsRegistrar registrar = new ProxyRuntimeHintsRegistrar(dlbf.getAutowireCandidateResolver());
registrar.registerRuntimeHints(runtimeHints, constructorOrFactoryMethod);
}
}
private CodeBlock generateCodeForConstructor(RegisteredBean registeredBean, Constructor<?> constructor) {
ConstructorDescriptor descriptor = new ConstructorDescriptor(
registeredBean.getBeanName(), constructor, registeredBean.getBeanClass());
Class<?> publicType = descriptor.publicType();
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {
return generateCodeForInaccessibleConstructor(descriptor,
hints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));View on GitHub (pinned to 69bf83ad71)