spring-projects/spring-framework · critical · BeanInstantiationException

Unresolvable class definition

Error message

Unresolvable class definition

What it means

Thrown as BeanInstantiationException by instantiateClass(Class) at BeanUtils.java:147 when getDeclaredConstructor() raises a LinkageError (e.g. NoClassDefFoundError, UnsatisfiedLinkError, IncompatibleClassChangeError). This signals a class-resolution/classloader problem rather than a missing constructor: the class was loaded but its dependencies could not be resolved.

Solutions

  1. Read the LinkageError cause (often NoClassDefFoundError) to identify the missing class.
  2. Add the missing dependency JAR to the runtime classpath (it may be present at compile time only).
  3. Resolve version mismatches by aligning the dependency versions across modules.
  4. Check classloader/JPMS 'requires' and 'opens' visibility; rebuild the affected module.

Example fix

// before: ctor references com.library.Config which is not on runtime classpath
BeanUtils.instantiateClass(MyService.class); // NoClassDefFoundError wrapped

// after: ensure dependency present at runtime (gradle)
// dependencies { runtimeOnly 'com.library:library-config:1.2.0' }
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the class is resolvable with its references
try {
    clazz.getDeclaredConstructor();
} catch (LinkageError | NoClassDefFoundError e) {
    // do not attempt instantiation; fix classpath first
}

Type guard

static boolean linkageClean(Class<?> c) {
    try { c.getDeclaredConstructor(); return true; }
    catch (LinkageError | NoSuchMethodException e) { return false; }
}

Try / catch

try {
    BeanUtils.instantiateClass(clazz);
} catch (BeanInstantiationException ex) {
    if (ex.getCause() instanceof LinkageError link) {
        // missing dependency/classloader issue; surface the missing class
        throw new IllegalStateException("missing runtime class: " + link.getMessage(), link);
    }
    throw ex;
}

Prevention

When it happens

Trigger: Instantiating a class that references, in its constructor signature or field types, another class missing from the runtime classpath/module graph; a stale compiled class referencing a removed dependency; split-package or classloader-visibility issues in an app server/OSGi/JPMS environment; a native library unsatisfied at load time.

Common situations: Missing optional dependency JAR at runtime; version skew where a class was compiled against a newer API; fat-jar shading that dropped a transitive class; modular runtime (jlink) missing 'requires'; deployed WAR missing a lib; upgrade/downgrade of Spring or another lib leaving dangling references.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/BeanUtils.java:147

	 * @see Constructor#newInstance
	 */
	public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
		Assert.notNull(clazz, "Class must not be null");
		if (clazz.isInterface()) {
			throw new BeanInstantiationException(clazz, "Specified class is an interface");
		}
		Constructor<T> ctor;
		try {
			ctor = clazz.getDeclaredConstructor();
		}
		catch (NoSuchMethodException ex) {
			ctor = findPrimaryConstructor(clazz);
			if (ctor == null) {
				throw new BeanInstantiationException(clazz, "No default constructor found", ex);
			}
		}
		catch (LinkageError err) {
			throw new BeanInstantiationException(clazz, "Unresolvable class definition", err);
		}
		return instantiateClass(ctor);
	}

	/**
	 * Instantiate a class using its no-arg constructor and return the new instance
	 * as the specified assignable type.
	 * <p>Useful in cases where the type of the class to instantiate (clazz) is not
	 * available, but the type desired (assignableTo) is known.
	 * <p>Note that this method tries to set the constructor accessible if given a
	 * non-accessible (that is, non-public) constructor.
	 * @param clazz class to instantiate
	 * @param assignableTo type that clazz must be assignableTo
	 * @return the new instance
	 * @throws BeanInstantiationException if the bean cannot be instantiated
	 * @see Constructor#newInstance
	 */
	@SuppressWarnings("unchecked")

View on GitHub (pinned to 69bf83ad71)