spring-projects/spring-framework · error · AopConfigException

Unable to instantiate proxy using Objenesis, and regular…

Error message

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

What it means

Thrown by ObjenesisCglibAopProxy.createProxyClassAndInstance when Objenesis instantiation fails AND the fallback default-constructor instantiation also fails. Spring tries Objenesis first to bypass constructors; if it is unavailable/disabled, it falls back to the proxy class's constructor, and only if both fail does it raise AopConfigException wrapping the constructor error. The root cause is in the nested exception.

Solutions

  1. Inspect the nested cause (the Throwable passed to AopConfigException) — it is usually the real reason: a missing opens, a SecurityException, or a constructor exception.
  2. On JDK 16+, add the required --add-opens exports (typically java.base/java.lang=ALL-UNNAMED) so Objenesis can allocate.
  3. Ensure spring-core's Objenesis is on the classpath and not stripped (don't exclude spring-objenesis); otherwise add a public no-arg constructor to the target class.
  4. If proxying is impossible (final constructor restrictions), switch to JDK interface proxies by setting interfaces on the proxy config.

Example fix

// before
class Service { // only constructor throws
  Service() { throw new IllegalStateException("no config"); }
}
ProxyFactory pf = new ProxyFactory(new Service());
pf.setProxyTargetClass(true);
pf.getProxy(); // -> Unable to instantiate proxy

// after
class Service {
  Service() { /* safe */ }
  Service(Config cfg) { ... }
}
// or add the JVM opens:
//   --add-opens java.base/java.lang=ALL-UNNAMED
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure target class can be instantiated by Objenesis or has a usable ctor
Class<?> tc = factory.getTargetClass();
if (tc != null) {
  boolean hasCtor = Arrays.stream(tc.getDeclaredConstructors())
      .anyMatch(c -> c.getParameterCount() == 0);
  if (!SpringObjenesisInstance.isWorthTrying() && !hasCtor) {
    throw new IllegalStateException(tc + " has no default constructor and Objenesis is unavailable");
  }
}

Type guard

static boolean instantiableAsCglibProxy(Class<?> c) {
  int mods = c.getModifiers();
  if (Modifier.isFinal(mods)) return false;
  return Arrays.stream(c.getDeclaredConstructors()).anyMatch(k -> k.getParameterCount() == 0)
      || objenesis.isWorthTrying();
}

Try / catch

try { proxy = factory.getProxy(); }
catch (AopConfigException e) {
  Throwable cause = e.getCause();
  log.error("CGLIB instantiation failed; cause={}", cause);
  // add --add-opens, fix constructor, or fall back to JDK interface proxy
}

Prevention

When it happens

Trigger: CGLIB class proxy of a target whose proxy class cannot be instantiated: a class with only private/throwing constructors on a JVM where Objenesis is suppressed (JPMS 'opens' missing, GraalVM native image, Android); a constructor that throws; a final/ultra-restricted class. The fallback at lines 75-88 catches Throwable from getDeclaredConstructor/newInstance and rethrows this AopConfigException.

Common situations: Missing '--add-opens java.base/java.lang=ALL-UNNAMED' on JDK 16+ for CGLIB/Objenesis; proxying a Kotlin class with required-arg constructor under a build that strips Objenesis; Spring Boot on a restricted JRE; constructor that initializes a field that fails (e.g. missing dependency).

Related errors


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

Appendix: 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 69bf83ad71)