spring-projects/spring-framework · error · AotBeanProcessingException

failed to generate code for bean definition

Error message

failed to generate code for bean definition

What it means

Thrown as an AotBeanProcessingException when generating the code to register a bean definition fails for any reason other than an AotException. BeanRegistrationsAotContribution.generateRegisterBeanDefinitionMethods calls generateBeanRegistration per bean; any generic Exception during code generation (reflection lookup, JavaPoet build, value resolution) is wrapped with the registered bean and the message 'failed to generate code for bean definition' so you know which bean broke AOT processing.

Solutions

  1. Read the wrapped 'caused by' to find the real codegen error; the registeredBean in the exception names the offending bean.
  2. Refactor the offending bean to a form Spring can AOT-process (concrete class or plain @Bean/@Configuration factory method, no lambda instance supplier).
  3. Remove or exclude the bean from AOT processing if it is inherently dynamic.
  4. Clean generated sources and regenerate (mvn/gradle clean) after fixing the underlying cause.
  5. Align Spring module versions to eliminate codegen-path mismatches.

Example fix

// before: lambda instance supplier Spring cannot AOT-generate
@Bean
public MyBean myBean = () -> new MyBean(loadFromDb());

// after: a @Bean method Spring can process at AOT time
@Bean
public MyBean myBean(DataSource ds) {
    return new MyBean(loadFromDb(ds));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect beans that AOT cannot handle before running the native build
RootBeanDefinition mbd = (RootBeanDefinition) registeredBean.getMergedBeanDefinition();
if (mbd.getInstanceSupplier() != null || mbd.getFactoryMethodName() == null && !mbd.hasBeanClass()) {
    throw new IllegalStateException("Bean not AOT-friendly: " + registeredBean.getBeanName());
}

Try / catch

try {
    aotContribution.applyTo(generationContext, codeGenerator);
} catch (AotBeanProcessingException ex) {
    RegisteredBean rb = ex.getRegisteredBean();
    throw new ConfigurationException("AOT failed for bean " + rb.getBeanName(), ex);
}

Prevention

When it happens

Trigger: Any uncaught Exception (not subclass of AotException) thrown while BeanDefinitionMethodGenerator generates the bean-registration method for a single Registration during the AOT processing phase. Causes include unsupported bean definition shapes, missing classes, value codegen failures, and reflective metadata errors.

Common situations: Enabling Spring AOT / native-image on a context that contains a bean Spring cannot statically describe (lambda @Bean, programmatic instance supplier, dynamic bean definitions); using a third-party BeanDefinitionRegistryPostProcessor that adds unsupported metadata; upgrading Spring with stale generated sources; missing classes referenced only reflectively.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/e0581ca8f229e84b. Report an issue: GitHub.

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java:280

			});
		}


		private void generateRegisterBeanDefinitionMethods(MethodSpec.Builder method,
				Iterable<Registration> registrations) {

			CodeBlock.Builder code = CodeBlock.builder();
			registrations.forEach(registration -> {
				try {
					CodeBlock methodInvocation = generateBeanRegistration(registration);
					code.addStatement("$L.registerBeanDefinition($S, $L)",
							BEAN_FACTORY_PARAMETER_NAME, registration.beanName(), methodInvocation);
				}
				catch (AotException ex) {
					throw ex;
				}
				catch (Exception ex) {
					throw new AotBeanProcessingException(registration.registeredBean,
							"failed to generate code for bean definition", ex);
				}
			});
			method.addCode(code.build());
		}

		private CodeBlock generateBeanRegistration(Registration registration) {
			MethodReference beanDefinitionMethod = registration.methodGenerator
					.generateBeanDefinitionMethod(this.generationContext, this.codeGenerator);
			return beanDefinitionMethod.toInvokeCodeBlock(
					ArgumentCodeGenerator.none(), this.codeGenerator.getClassName());
		}
	}

}

View on GitHub (pinned to 69bf83ad71)