# java.lang.ClassCastException: class com.sun.proxy.$Proxy0 cannot be cast to class com.example.MyInterface (com.sun.proxy.$Proxy0 is in module java.base of loader 'app'; com.example.MyInterface is in unnamed module of loader 'app')

- **ID:** `java/classcastexception-proxy-invocationhandler`
- **Domain:** java
- **Category:** type_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

This error occurs when a JDK dynamic proxy (Proxy.newProxyInstance) is created for an interface that is not visible to the proxy's class loader, typically because the interface is loaded by a different class loader or the proxy class is from a different module.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Java 8 | active | — | — |
| Java 11 | active | — | — |
| Java 17 | active | — | — |
| Spring Framework 5.3.x | active | — | — |
| Spring Framework 6.x | active | — | — |

## Workarounds

1. **Ensure the interface is loaded by the same class loader as the proxy: `ClassLoader commonLoader = Thread.currentThread().getContextClassLoader(); MyInterface proxy = (MyInterface) Proxy.newProxyInstance(commonLoader, new Class[]{MyInterface.class}, handler);`** (85% success)
   ```
   Ensure the interface is loaded by the same class loader as the proxy: `ClassLoader commonLoader = Thread.currentThread().getContextClassLoader(); MyInterface proxy = (MyInterface) Proxy.newProxyInstance(commonLoader, new Class[]{MyInterface.class}, handler);`
   ```
2. **For Spring applications, configure proxy-target-class="true" to use CGLIB proxies instead of JDK dynamic proxies: `<aop:aspectj-autoproxy proxy-target-class="true"/>` or `@EnableAspectJAutoProxy(proxyTargetClass = true)`.** (90% success)
   ```
   For Spring applications, configure proxy-target-class="true" to use CGLIB proxies instead of JDK dynamic proxies: `<aop:aspectj-autoproxy proxy-target-class="true"/>` or `@EnableAspectJAutoProxy(proxyTargetClass = true)`.
   ```
3. **Move the interface definition to a shared library jar that is loaded by the common class loader (e.g., the bootstrap or extension class loader) to avoid class loader isolation.** (80% success)
   ```
   Move the interface definition to a shared library jar that is loaded by the common class loader (e.g., the bootstrap or extension class loader) to avoid class loader isolation.
   ```

## Dead Ends

- **Casting the proxy to the concrete class instead of the interface** — JDK dynamic proxies only implement interfaces, not concrete classes; casting to a concrete class will always fail. (95% fail)
- **Adding the interface to the classpath multiple times in different jars** — Multiple class loaders loading the same interface cause type identity issues; the proxy implements one version, but the cast expects another. (70% fail)
- **Using CGLIB proxies instead without changing the interface visibility** — CGLIB creates subclass proxies, which also require the target class to be accessible; the root cause (class loader mismatch) remains. (60% fail)
