{"record":{"id":"3f3ce769e7b541ed","repo":"spring-projects/spring-framework","slug":"unable-to-instantiate-proxy-using-objenesis-and-r","errorCode":null,"errorMessage":"Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well","messagePattern":"Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java","lineNumber":86,"sourceCode":"\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tlogger.debug(\"Unable to instantiate proxy using Objenesis, \" +\n\t\t\t\t\t\t\"falling back to regular proxy construction\", ex);\n\t\t\t}\n\t\t}\n\n\t\tif (proxyInstance == null) {\n\t\t\t// Regular instantiation via default constructor...\n\t\t\ttry {\n\t\t\t\tConstructor<?> ctor = (this.constructorArgs != null ?\n\t\t\t\t\t\tproxyClass.getDeclaredConstructor(this.constructorArgTypes) :\n\t\t\t\t\t\tproxyClass.getDeclaredConstructor());\n\t\t\t\tReflectionUtils.makeAccessible(ctor);\n\t\t\t\tproxyInstance = (this.constructorArgs != null ?\n\t\t\t\t\t\tctor.newInstance(this.constructorArgs) : ctor.newInstance());\n\t\t\t}\n\t\t\tcatch (Throwable ex) {\n\t\t\t\tthrow new AopConfigException(\"Unable to instantiate proxy using Objenesis, \" +\n\t\t\t\t\t\t\"and regular proxy instantiation via default constructor fails as well\", ex);\n\t\t\t}\n\t\t}\n\n\t\t((Factory) proxyInstance).setCallbacks(callbacks);\n\t\treturn proxyInstance;\n\t}\n\n}\n","sourceCodeStart":68,"sourceCodeEnd":96,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/ObjenesisCglibAopProxy.java#L68-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Inspect the nested cause (the Throwable passed to AopConfigException) — it is usually the real reason: a missing opens, a SecurityException, or a constructor exception.","On JDK 16+, add the required --add-opens exports (typically java.base/java.lang=ALL-UNNAMED) so Objenesis can allocate.","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.","If proxying is impossible (final constructor restrictions), switch to JDK interface proxies by setting interfaces on the proxy config."],"exampleFix":"// before\nclass Service { // only constructor throws\n  Service() { throw new IllegalStateException(\"no config\"); }\n}\nProxyFactory pf = new ProxyFactory(new Service());\npf.setProxyTargetClass(true);\npf.getProxy(); // -> Unable to instantiate proxy\n\n// after\nclass Service {\n  Service() { /* safe */ }\n  Service(Config cfg) { ... }\n}\n// or add the JVM opens:\n//   --add-opens java.base/java.lang=ALL-UNNAMED","handlingStrategy":"try-catch","validationCode":"// Pre-flight: ensure target class can be instantiated by Objenesis or has a usable ctor\nClass<?> tc = factory.getTargetClass();\nif (tc != null) {\n  boolean hasCtor = Arrays.stream(tc.getDeclaredConstructors())\n      .anyMatch(c -> c.getParameterCount() == 0);\n  if (!SpringObjenesisInstance.isWorthTrying() && !hasCtor) {\n    throw new IllegalStateException(tc + \" has no default constructor and Objenesis is unavailable\");\n  }\n}","typeGuard":"static boolean instantiableAsCglibProxy(Class<?> c) {\n  int mods = c.getModifiers();\n  if (Modifier.isFinal(mods)) return false;\n  return Arrays.stream(c.getDeclaredConstructors()).anyMatch(k -> k.getParameterCount() == 0)\n      || objenesis.isWorthTrying();\n}","tryCatchPattern":"try { proxy = factory.getProxy(); }\ncatch (AopConfigException e) {\n  Throwable cause = e.getCause();\n  log.error(\"CGLIB instantiation failed; cause={}\", cause);\n  // add --add-opens, fix constructor, or fall back to JDK interface proxy\n}","preventionTips":["Keep a public/protected no-arg constructor on classes you will proxy with CGLIB.","On JDK 16+, configure Spring Boot with the spring.aot or add-opens arguments.","Inspect the nested cause — it is the real reason, not the wrapper message."],"tags":["spring-aop","cglib","objenesis","proxy","jpms"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}