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

  1. 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'.
  2. Refactor the factory method to a non-suspending method or a plain constructor so the code generator can emit code for it.
  3. Update Spring Framework to a version whose InstanceSupplierCodeGenerator supports the executable shape you are using.
  4. Register the bean differently (constructor injection, or a non-suspending @Bean method that bridges the coroutine internally).
  5. 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

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


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)