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
InstanceSupplierCodeGenerator.generateCode only knows how to emit creation code for a Constructor or a (non-Kotlin-suspending) Method. If the resolved InstantiationDescriptor's executable is neither - for example a Kotlin suspending function used as a factory method, or an exotic executable - it throws AotBeanProcessingException stating no suitable constructor/factory method was found.
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 e8729d0438)
Solutions
- Avoid using a Kotlin suspending function as a bean factory method; use a regular (non-suspending) function or constructor.
- Provide an explicit non-suspending factory method or constructor for the bean.
- If the executable type is unexpected, ensure the InstantiationDescriptor resolves to a Constructor or Method.
Example fix
// before (Kotlin) @Bean fun makeBean() = someSuspendingCall() // suspending // after @Bean fun makeBean() = blockingCreate() // non-suspending
Defensive patterns
Strategy: validation
Validate before calling
Executable e = instantiationDescriptor.executable();
boolean suspending = KotlinDetector.isSuspendingFunction(e);
if (!(e instanceof Constructor) && (!(e instanceof Method) || suspending)) {
throw new IllegalStateException("No AOT-supported executable: " + e);
} Type guard
boolean isAotSupportedExecutable(Executable e) {
return e instanceof Constructor || (e instanceof Method m && !KotlinDetector.isSuspendingFunction(m));
} Prevention
- Do not use Kotlin suspending functions as bean factory methods.
- Prefer constructors or regular factory methods for native targets.
- Validate bean executables during the AOT dry-run.
When it happens
Trigger: A bean's resolved instantiation executable is a Kotlin suspending factory method, or otherwise not a plain Constructor/Method during AOT instance-supplier code generation.
Common situations: Kotlin beans instantiated via a suspending companion/object function as a factory method in a native build; beans whose instantiation descriptor could not be resolved to a standard executable.
Related errors
- Argument type mismatch: expected '{}' for value [{}]
- Failed to load Class [{}] from ClassLoader [{}]
- Unexpected MethodOverride subclass: {}
- Unsupported executable: {}
- Cannot invoke instance method without factoryBeanName: {}
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/7d97f51ff4d798c9.json.
Report an issue: GitHub.