spring-projects/spring-framework · error · BeanCreationException

Resolution of declared constructors on bean Class

Error message

Resolution of declared constructors on bean Class [{}] from ClassLoader [{}] failed

What it means

BeanCreationException thrown by determineCandidateConstructors when Class.getDeclaredConstructors() throws (any Throwable). This wraps reflection failures — typically classloader/scoping problems, security manager denials, or a malformed/garbage class — so constructor-based autowiring cannot proceed for the named bean class and its classloader.

Solutions

  1. Inspect the root cause (the wrapped Throwable) — most often a NoClassDefFoundError/LinkageError naming the missing type.
  2. Ensure the bean class and all its constructor parameter types are loadable by the same classloader.
  3. Disable/remove bytecode agents or devtools restart if they corrupt the class.
  4. Add the reflective access (class.getDeclaredConstructors) to the permitted set if running under a SecurityManager or strong encapsulation.

Example fix

// before — bean constructor references a type not visible to its classloader
public OrderProcessor(PaymentGateway gw) { ... }

// after — ensure PaymentGateway is on the same classpath / module exports it
// (fix module-info or dependency, then restart)
module app {
    requires payments.api;
    opens com.example to spring.core;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe reflectability before bean creation
try {
    beanClass.getDeclaredConstructors();
} catch (Throwable t) {
    throw new IllegalStateException("class not reflectable: " + beanClass, t);
}

Type guard

static boolean isReflectable(Class<?> c) {
    try { c.getDeclaredConstructors(); return true; } catch (Throwable t) { return false; }
}

Try / catch

try {
    beanClass.getDeclaredConstructors();
} catch (LinkageError | SecurityException ex) {
    // fix classloader/encapsulation, then rethrow with context
    throw new BeanCreationException(beanName, "constructor resolution failed", ex);
}

Prevention

When it happens

Trigger: getDeclaredConstructors() fails on the bean class during @Autowired constructor discovery: class verified but not reflectable, a sealed/hidden class, a stale hot-swapped class, SecurityManager denying reflection, or a corrupted class file in a custom classloader.

Common situations: Devtools/restart classloader mismatches; custom classloaders returning broken Class objects; agents/bytecode tools weaving incompatible constructors; restricted (sealed) classes in newer JDKs.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java:366

	@Override
	public Constructor<?> @Nullable [] determineCandidateConstructors(Class<?> beanClass, final String beanName)
			throws BeanCreationException {

		checkLookupMethods(beanClass, beanName);

		// Quick check on the concurrent map first, with minimal locking.
		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
		if (candidateConstructors == null) {
			// Fully synchronized resolution now...
			synchronized (this.candidateConstructorsCache) {
				candidateConstructors = this.candidateConstructorsCache.get(beanClass);
				if (candidateConstructors == null) {
					Constructor<?>[] rawCandidates;
					try {
						rawCandidates = beanClass.getDeclaredConstructors();
					}
					catch (Throwable ex) {
						throw new BeanCreationException(beanName,
								"Resolution of declared constructors on bean Class [" + beanClass.getName() +
								"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
					}
					List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
					Constructor<?> requiredConstructor = null;
					Constructor<?> defaultConstructor = null;
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
					int nonSyntheticConstructors = 0;
					for (Constructor<?> candidate : rawCandidates) {
						if (!candidate.isSynthetic()) {
							nonSyntheticConstructors++;
						}
						else if (primaryConstructor != null) {
							continue;
						}
						MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
						if (ann == null) {
							Class<?> userClass = ClassUtils.getUserClass(beanClass);

View on GitHub (pinned to 69bf83ad71)