spring-projects/spring-framework · error · AopConfigException

Unable to instantiate proxy using Objenesis, and regular pro

Error message

Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well

What it means

Thrown by ObjenesisCglibAopProxy when the CGLIB proxy class was generated but no instance could be created. Spring first tries Objenesis (a byte-code library that bypasses constructors), and if that fails it falls back to invoking a default (or configured) constructor via reflection. This exception means BOTH paths failed, so the proxied class effectively cannot be instantiated. It wraps the underlying cause (typically a constructor exception or Objenesis limitation) as its cause.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java:86

			}
			catch (Throwable ex) {
				logger.debug("Unable to instantiate proxy using Objenesis, " +
						"falling back to regular proxy construction", ex);
			}
		}

		if (proxyInstance == null) {
			// Regular instantiation via default constructor...
			try {
				Constructor<?> ctor = (this.constructorArgs != null ?
						proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
						proxyClass.getDeclaredConstructor());
				ReflectionUtils.makeAccessible(ctor);
				proxyInstance = (this.constructorArgs != null ?
						ctor.newInstance(this.constructorArgs) : ctor.newInstance());
			}
			catch (Throwable ex) {
				throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
						"and regular proxy instantiation via default constructor fails as well", ex);
			}
		}

		((Factory) proxyInstance).setCallbacks(callbacks);
		return proxyInstance;
	}

}

View on GitHub (pinned to e8729d0438)

Solutions

  1. Ensure the target class has a public no-arg constructor, or supply matching constructor-arg types/values to ProxyFactory.
  2. If using Spring DI, ensure the proxied bean is itself constructed by Spring and the proxy wraps an instance rather than needing instantiation.
  3. Upgrade/verify the Objenesis dependency is on the classpath and not disabled (SpringObjenesis.isWorthTrying()).
  4. Inspect the wrapped cause in the stack trace - it usually names the exact missing constructor or the constructor failure.

Example fix

// before
class Service { Service(Dep dep) { ... } } // only one constructor
ProxyFactory pf = new ProxyFactory();
pf.setTarget(new Service(dep));

// after: provide constructor args to the proxy
ProxyFactory pf = new ProxyFactory();
pf.setTargetClass(Service.class);
pf.setConstructorArgTypes(new Class[]{Dep.class});
pf.setConstructorArguments(new Object[]{dep});
Defensive patterns

Strategy: validation

Validate before calling

// Before building a class proxy, ensure instantiability
Class<?> targetClass = pf.getTargetClass();
boolean hasNoArgCtor = java.util.Arrays.stream(targetClass.getDeclaredConstructors())
    .anyMatch(c -> c.getParameterCount() == 0);
if (!hasNoArgCtor && (pf.getConstructorArguments() == null)) {
    throw new IllegalStateException("Target has no usable constructor for CGLIB proxy: " + targetClass);
}

Type guard

public static boolean canProxyInstantiate(ProxyFactory pf) {
    Class<?> c = pf.getTargetClass();
    return c != null && !Modifier.isAbstract(c.getModifiers()) && !Modifier.isInterface(c.getModifiers());
}

Try / catch

try {
    return pf.getProxy();
} catch (AopConfigException ex) {
    Throwable cause = ex.getCause();
    if (cause != null && cause.getMessage().contains("constructor")) {
        throw new IllegalStateException("Missing no-arg constructor for proxy target", cause);
    }
    throw ex;
}

Prevention

When it happens

Trigger: Triggered during getProxy() for a class-based (proxyTargetClass=true) AOP proxy when the target class has no accessible no-arg constructor AND Objenesis cannot create the instance (e.g. objenesis.isWorthTrying() returned false or threw). Also when a configured constructor-arg type does not match any declared constructor of the generated proxy class.

Common situations: Proxied class declares only a non-default constructor with required args and no matching constructor-args were supplied to ProxyFactory; running on a JVM/module configuration where Objenesis is disabled; the target's default constructor itself throws; proxying a class with a private no-arg constructor on a strict JPMS setup that blocks deep reflection.

Related errors


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