{"record":{"id":"d438748e71a632fe","repo":"spring-projects/spring-framework","slug":"cannot-create-class-proxy-for-targetsource-with-nu","errorCode":null,"errorMessage":"Cannot create class proxy for TargetSource with null target class","messagePattern":"Cannot create class proxy for TargetSource with null target class","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactory.java","lineNumber":161,"sourceCode":"\t * @param proxyInterface the interface that the proxy should implement\n\t * @param targetSource the TargetSource that the proxy should invoke\n\t * @return the proxy object\n\t * @see #ProxyFactory(Class, org.springframework.aop.TargetSource)\n\t */\n\t@SuppressWarnings(\"unchecked\")\n\tpublic static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {\n\t\treturn (T) new ProxyFactory(proxyInterface, targetSource).getProxy();\n\t}\n\n\t/**\n\t * Create a proxy for the specified {@code TargetSource} that extends\n\t * the target class of the {@code TargetSource}.\n\t * @param targetSource the TargetSource that the proxy should invoke\n\t * @return the proxy object\n\t */\n\tpublic static Object getProxy(TargetSource targetSource) {\n\t\tif (targetSource.getTargetClass() == null) {\n\t\t\tthrow new IllegalArgumentException(\"Cannot create class proxy for TargetSource with null target class\");\n\t\t}\n\t\tProxyFactory proxyFactory = new ProxyFactory();\n\t\tproxyFactory.setTargetSource(targetSource);\n\t\tproxyFactory.setProxyTargetClass(true);\n\t\treturn proxyFactory.getProxy();\n\t}\n\n}\n","sourceCodeStart":143,"sourceCodeEnd":170,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactory.java#L143-L170","documentation":"Thrown by the static helper ProxyFactory.getProxy(TargetSource) when targetSource.getTargetClass() == null. That overload forces proxyTargetClass=true (a CGLIB class proxy), so a concrete target class is mandatory. It fails fast rather than handing a null class to the CGLIB proxy factory.","triggerScenarios":"Calling ProxyFactory.getProxy(targetSource) where the TargetSource has no concrete class: an empty/abstract TargetSource whose getTargetClass() returns null; a custom TargetSource that lazily resolves the class but does not expose it; passing an EmptyTargetSource.","commonSituations":"Hand-rolled TargetSource for pooling/thread-local that forgot to implement getTargetClass(); passing a TargetSource built for an interface-only proxy into the class-proxy overload; mis-wiring in remoting/scoped-proxy code.","solutions":["Use a TargetSource that returns a concrete class, e.g. new SingletonTargetSource(myBean) or implement getTargetClass() to return the implementation class.","If you only have an interface, use the overload ProxyFactory.getProxy(Class<T> proxyInterface, TargetSource ts) instead, which builds a JDK proxy.","Construct the ProxyFactory manually with setTargetSource + setInterfaces if you need both behaviors."],"exampleFix":"// before\nTargetSource ts = new EmptyTargetSource(null, true);\nObject p = ProxyFactory.getProxy(ts); // -> null target class\n\n// after\nTargetSource ts = new SingletonTargetSource(new MyServiceImpl());\nObject p = ProxyFactory.getProxy(ts);","handlingStrategy":"validation","validationCode":"if (targetSource.getTargetClass() == null) {\n  throw new IllegalArgumentException(\"TargetSource \" + targetSource + \" exposes no target class\");\n}\nObject proxy = ProxyFactory.getProxy(targetSource);","typeGuard":"static boolean hasConcreteTargetClass(TargetSource ts) { return ts.getTargetClass() != null && !ts.getTargetClass().isInterface(); }","tryCatchPattern":"try { return ProxyFactory.getProxy(ts); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"null target class\")) { /* swap in SingletonTargetSource */ }\n  throw e;\n}","preventionTips":["Prefer SingletonTargetSource(bean) which always exposes a concrete class.","Implement getTargetClass() in custom TargetSource implementations.","Use the interface overload ProxyFactory.getProxy(Class, TargetSource) when only an interface is available."],"tags":["spring-aop","proxy","target-source","configuration"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}