spring-projects/spring-framework · error · IllegalArgumentException
Cannot create class proxy for TargetSource with null target…
Error message
Cannot create class proxy for TargetSource with null target class
What it means
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.
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.
Example fix
// before TargetSource ts = new EmptyTargetSource(null, true); Object p = ProxyFactory.getProxy(ts); // -> null target class // after TargetSource ts = new SingletonTargetSource(new MyServiceImpl()); Object p = ProxyFactory.getProxy(ts);
Defensive patterns
Strategy: validation
Validate before calling
if (targetSource.getTargetClass() == null) {
throw new IllegalArgumentException("TargetSource " + targetSource + " exposes no target class");
}
Object proxy = ProxyFactory.getProxy(targetSource); Type guard
static boolean hasConcreteTargetClass(TargetSource ts) { return ts.getTargetClass() != null && !ts.getTargetClass().isInterface(); } Try / catch
try { return ProxyFactory.getProxy(ts); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("null target class")) { /* swap in SingletonTargetSource */ }
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- TargetSource cannot determine target class: Either an…
- Unexpected AOP exception
- Advice must be declared inside an aspect type: Offending…
- Advice object [ ] is neither a supported subinterface of…
- AdvisorAutoProxyCreator requires a…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/d438748e71a632fe.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactory.java:161
* @param proxyInterface the interface that the proxy should implement
* @param targetSource the TargetSource that the proxy should invoke
* @return the proxy object
* @see #ProxyFactory(Class, org.springframework.aop.TargetSource)
*/
@SuppressWarnings("unchecked")
public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
}
/**
* Create a proxy for the specified {@code TargetSource} that extends
* the target class of the {@code TargetSource}.
* @param targetSource the TargetSource that the proxy should invoke
* @return the proxy object
*/
public static Object getProxy(TargetSource targetSource) {
if (targetSource.getTargetClass() == null) {
throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(targetSource);
proxyFactory.setProxyTargetClass(true);
return proxyFactory.getProxy();
}
}
View on GitHub (pinned to 69bf83ad71)