Can not set field to com.sun.proxy.Proxy
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The error "Can not set field to com.sun.proxy.$Proxy" occurs in Java when code tries to inject or assign a JDK dynamic proxy object to a field that expects a concrete class type. JDK proxies implement interfaces only — they cannot be cast to concrete classes. This error is most common in Spring applications where beans are proxied for AOP (aspect-oriented programming), transactions, or scoping. The fix is to program to interfaces rather than implementations, or switch to CGLIB proxies that can proxy concrete classes.
Why the Error Happens
When Spring creates a JDK dynamic proxy for UserServiceImpl, the proxy implements the UserService interface. The proxy object's type is com.sun.proxy.$Proxy, not UserServiceImpl. Injecting into a field of type UserServiceImpl fails because the proxy is not assignable to the concrete class.
Fix 1: Inject by Interface (Recommended)
Always declare fields, constructor parameters, and method parameters using the interface type rather than the implementation class. This follows the Dependency Inversion Principle and works with all proxy types.
Fix 2: Enable CGLIB Proxies
Or in application.properties:
CGLIB proxies subclass the concrete class instead of implementing interfaces, so the proxy IS an instance of UserServiceImpl. Spring Boot 2.x+ defaults to CGLIB proxies, but this can be overridden by configuration or specific annotations.
Fix 3: XML Configuration
For Spring XML-based configuration, add proxy-target-class="true" to the relevant AOP or transaction configuration elements.
JDK Proxy vs CGLIB Proxy
| Feature | JDK Proxy | CGLIB Proxy |
| Mechanism | Implements interfaces | Subclasses concrete class |
| Requires interface | Yes | No |
| Proxy final classes | N/A | No (cannot subclass final) |
| Proxy final methods | N/A | No (cannot override final) |
| Performance | Slightly faster creation | Slightly faster invocation |
| Default in Spring Boot 2+ | No | Yes |
Common Scenarios That Trigger This Error
Debugging Proxy Type
Use AopUtils to inspect whether a bean is proxied and which proxy mechanism is in use. This helps diagnose which beans are affected.
Common Pitfalls
- Injecting by concrete class type: The most common cause. Always use the interface type for
@Autowiredfields. If no interface exists, either create one or ensure CGLIB proxying is enabled. - Mixing JDK and CGLIB proxy settings: Different Spring modules (AOP, transactions, cache) can have independent proxy settings. Ensure consistency by setting
spring.aop.proxy-target-class=trueglobally in application.properties. - Final classes with CGLIB: CGLIB cannot subclass
finalclasses. If you switch to CGLIB proxies and havefinalservice classes, you get a different error. Removefinalfrom classes that need proxying. - ScopedProxyMode.INTERFACES with concrete injection: When using request-scoped or session-scoped beans with
ScopedProxyMode.INTERFACES, the proxy only implements interfaces. UseScopedProxyMode.TARGET_CLASSfor CGLIB-based scoped proxies. - Kotlin classes are final by default: In Kotlin, all classes are
finalunless markedopen. This breaks CGLIB proxies. Use thekotlin-springcompiler plugin (all-open) to automatically open Spring-annotated classes.
Summary
- The error occurs when a JDK dynamic proxy (interface-only) is injected into a field expecting a concrete class
- Fix by declaring fields as interface types rather than implementation classes
- Enable CGLIB proxies with
spring.aop.proxy-target-class=trueif interface-based injection is not possible - Spring Boot 2+ defaults to CGLIB proxies, but specific configurations can override this
- Use
AopUtils.isJdkDynamicProxy()andAopUtils.isCglibProxy()to diagnose proxy types - CGLIB cannot proxy
finalclasses — removefinalor use the Kotlinall-openplugin

