spring-projects/spring-framework · error · IllegalArgumentException

{} cannot be found on {}

Error message

{} cannot be found on {}

What it means

ConstructorLookup.get calls Class.getDeclaredConstructor(parameterTypes) to locate the constructor the AOT machinery intends to use; if no constructor matches the captured parameter types it throws NoSuchMethodException, which Spring wraps as IllegalArgumentException with this message. The bean class does not expose a constructor with the expected signature.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java:407

	/**
	 * Performs lookup of the {@link Constructor}.
	 */
	private static class ConstructorLookup extends ExecutableLookup {

		private final Class<?>[] parameterTypes;

		ConstructorLookup(Class<?>[] parameterTypes) {
			this.parameterTypes = parameterTypes;
		}

		@Override
		public Executable get(RegisteredBean registeredBean) {
			Class<?> beanClass = registeredBean.getMergedBeanDefinition().getBeanClass();
			try {
				return beanClass.getDeclaredConstructor(this.parameterTypes);
			}
			catch (NoSuchMethodException ex) {
				throw new IllegalArgumentException(
						"%s cannot be found on %s".formatted(this, beanClass.getName()), ex);
			}
		}

		@Override
		public String toString() {
			return "Constructor with parameter types [%s]".formatted(toCommaSeparatedNames(this.parameterTypes));
		}
	}


	/**
	 * Performs lookup of the factory {@link Method}.
	 */
	private static class FactoryMethodLookup extends ExecutableLookup {

		private final Class<?> declaringClass;

View on GitHub (pinned to e8729d0438)

Solutions

  1. Regenerate AOT/native artifacts after changing the bean class or its dependencies.
  2. Confirm the bean class on the runtime classpath is the same version used at AOT build time.
  3. For Kotlin/inner classes, verify the constructor shape (e.g. synthetic params) matches what AOT expects, or annotate the intended constructor explicitly.

Example fix

// before: AOT captured Service(Repo) but runtime class only has Service(Repo, Config)
// after: align runtime class with AOT and rebuild
// mvn -Pnative spring-boot:process-aot
Defensive patterns

Strategy: validation

Validate before calling

Class<?>[] paramTypes = ...; // captured AOT constructor params
Class<?> beanClass = registeredBean.getBeanClass();
try { beanClass.getDeclaredConstructor(paramTypes); }
catch (NoSuchMethodException e) {
  throw new IllegalStateException("Constructor " + Arrays.toString(paramTypes) + " missing on " + beanClass);
}

Type guard

boolean constructorExists(Class<?> beanClass, Class<?>[] params) {
  try { beanClass.getDeclaredConstructor(params); return true; }
  catch (NoSuchMethodException e) { return false; }
}

Prevention

When it happens

Trigger: AOT captured a set of constructor parameter types (from the resolved InstantiationDescriptor) but the bean class on the runtime classpath no longer declares a constructor with exactly those parameter types.

Common situations: Bean class changed (constructor signature edited, an overload added/removed) without regenerating AOT artifacts; runtime classpath has a different version of the class than AOT used; Kotlin/record/inner-class constructor quirks where the synthetic parameter differs.

Related errors


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