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

  1. Avoid using a Kotlin suspending function as a bean factory method; use a regular (non-suspending) function or constructor.
  2. Provide an explicit non-suspending factory method or constructor for the bean.
  3. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/7d97f51ff4d798c9.json. Report an issue: GitHub.