{"record":{"id":"408ebf8f680b877e","repo":"spring-projects/spring-framework","slug":"targetsource-cannot-determine-target-class-either","errorCode":null,"errorMessage":"TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.","messagePattern":"TargetSource cannot determine target class: Either an interface or a target is required for proxy creation\\.","errorType":"exception","errorClass":"AopConfigException","httpStatus":null,"severity":"error","filePath":"spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java","lineNumber":64,"sourceCode":" * @see AdvisedSupport#setInterfaces\n */\npublic class DefaultAopProxyFactory implements AopProxyFactory, Serializable {\n\n\t/**\n\t * Singleton instance of this class.\n\t * @since 6.0.10\n\t */\n\tpublic static final DefaultAopProxyFactory INSTANCE = new DefaultAopProxyFactory();\n\n\tprivate static final long serialVersionUID = 7930414337282325166L;\n\n\n\t@Override\n\tpublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {\n\t\tif (config.isOptimize() || config.isProxyTargetClass() || !config.hasUserSuppliedInterfaces()) {\n\t\t\tClass<?> targetClass = config.getTargetClass();\n\t\t\tif (targetClass == null && config.getProxiedInterfaces().length == 0) {\n\t\t\t\tthrow new AopConfigException(\"TargetSource cannot determine target class: \" +\n\t\t\t\t\t\t\"Either an interface or a target is required for proxy creation.\");\n\t\t\t}\n\t\t\tif (targetClass == null || targetClass.isInterface() ||\n\t\t\t\t\tProxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {\n\t\t\t\treturn new JdkDynamicAopProxy(config);\n\t\t\t}\n\t\t\treturn new ObjenesisCglibAopProxy(config);\n\t\t}\n\t\telse {\n\t\t\treturn new JdkDynamicAopProxy(config);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":46,"sourceCodeEnd":79,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java#L46-L79","documentation":"Thrown by DefaultAopProxyFactory.createAopProxy when a CGLIB/class proxy is requested (optimize, proxyTargetClass, or no user interfaces) but the AdvisedSupport has neither a target class nor any proxied interfaces. The factory cannot decide what to subclass or implement, so it refuses to build a proxy. This is a configuration-time guard that fails fast instead of producing a useless proxy.","triggerScenarios":"Hit when (config.isOptimize() || config.isProxyTargetClass() || !config.hasUserSuppliedInterfaces()) is true AND config.getTargetClass() == null AND config.getProxiedInterfaces().length == 0. Concretely: new ProxyFactory().setProxyTargetClass(true) with no setTarget/setTargetSource/setInterfaces; or @EnableAsync(proxyTargetClass=true) on a bean whose TargetSource returns null target class (lazy/scoped proxy where the target bean is not resolvable yet).","commonSituations":"Forcing proxyTargetClass=true on an interface-only or target-less ProxyFactory; scoped-proxy/lazy-init targets whose TargetSource.getTargetClass() returns null because the backing bean does not exist yet; programmatic ProxyFactory use where setTarget was forgotten; upgrading and adding @EnableTransactionManagement(proxyTargetClass=true) while still expecting JDK interface proxies.","solutions":["Set a target or TargetSource on the proxy config before getProxy(), e.g. factory.setTarget(myBean) or factory.setTargetSource(ts) where ts.getTargetClass() is non-null.","Alternatively call factory.setInterfaces(MyInterface.class) so a JDK dynamic proxy is built instead of a class proxy.","If using @Enable* annotations with proxyTargetClass, ensure the target bean is resolvable (not a missing/lazy bean with null class).","Drop optimize/proxyTargetClass so the JDK path applies when only interfaces are available."],"exampleFix":"// before\nProxyFactory pf = new ProxyFactory();\npf.addAdvice(myInterceptor);\npf.setProxyTargetClass(true);\nObject proxy = pf.getProxy(); // -> TargetSource cannot determine target class\n\n// after\nProxyFactory pf = new ProxyFactory();\npf.setTarget(new MyServiceImpl());\npf.addAdvice(myInterceptor);\npf.setProxyTargetClass(true);\nObject proxy = pf.getProxy();","handlingStrategy":"validation","validationCode":"// Validate before getProxy()\nProxyCreatorSupport cfg = factory; // your AdvisedSupport / ProxyFactory\nboolean needsClass = cfg.isOptimize() || cfg.isProxyTargetClass() || !cfg.hasUserSuppliedInterfaces();\nif (needsClass && cfg.getTargetClass() == null && cfg.getProxiedInterfaces().length == 0) {\n    throw new IllegalStateException(\n        \"Refusing to build proxy: CGLIB mode with no target class and no interfaces.\");\n}","typeGuard":"static boolean canBuildProxy(AdvisedSupport c) {\n  boolean classMode = c.isOptimize() || c.isProxyTargetClass() || !c.hasUserSuppliedInterfaces();\n  return !classMode || c.getTargetClass() != null || c.getProxiedInterfaces().length > 0;\n}","tryCatchPattern":"try { proxy = factory.getProxy(); }\ncatch (AopConfigException e) {\n  if (e.getMessage().contains(\"cannot determine target class\")) { /* set target or interfaces, then retry build */ }\n  else throw e;\n}","preventionTips":["Always pair setProxyTargetClass(true) with a concrete setTarget/setTargetSource.","When relying on autodetect interfaces, ensure a target bean is resolvable before getProxy().","In tests, assert factory.getTargetClass() != null before calling getProxy()."],"tags":["spring-aop","proxy","configuration","cglib"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}