#206 - Set class loader for dummy method proxies.

The Enhancer used to create the proxy instances wasn't explicitly
setting the class loader to use, which meant by default the proxied
class's class loader was chosen. This is fine for controller classes, but
in some containers the return types for the controller may have a
class loader that doesn't have access to Spring, resulting in
ClassNotFoundExceptions. For example, returning a JAX-RS class JBoss.
Using the controller's class loader when proxying the return type solves
this. 

Related issues: #136.
This commit is contained in:
Kory Markevich
2014-06-25 13:44:26 -07:00
committed by Oliver Gierke
parent d4d788d9e0
commit 921d1af9fb

View File

@@ -83,6 +83,7 @@ public class DummyInvocationUtils {
* (non-Javadoc)
* @see org.springframework.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy)
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
if (GET_INVOCATIONS.equals(method)) {
@@ -96,7 +97,7 @@ public class DummyInvocationUtils {
this.invocation = new SimpleMethodInvocation(targetType, method, args);
Class<?> returnType = method.getReturnType();
return returnType.cast(getProxyWithInterceptor(returnType, this));
return returnType.cast(getProxyWithInterceptor(returnType, this, obj.getClass().getClassLoader()));
}
/*
@@ -144,11 +145,11 @@ public class DummyInvocationUtils {
Assert.notNull(type, "Given type must not be null!");
InvocationRecordingMethodInterceptor interceptor = new InvocationRecordingMethodInterceptor(type, parameters);
return getProxyWithInterceptor(type, interceptor);
return getProxyWithInterceptor(type, interceptor, type.getClassLoader());
}
@SuppressWarnings("unchecked")
private static <T> T getProxyWithInterceptor(Class<?> type, InvocationRecordingMethodInterceptor interceptor) {
private static <T> T getProxyWithInterceptor(Class<?> type, InvocationRecordingMethodInterceptor interceptor, ClassLoader classLoader) {
if (type.isInterface()) {
@@ -164,6 +165,7 @@ public class DummyInvocationUtils {
enhancer.setSuperclass(type);
enhancer.setInterfaces(new Class<?>[] { LastInvocationAware.class });
enhancer.setCallbackType(org.springframework.cglib.proxy.MethodInterceptor.class);
enhancer.setClassLoader(classLoader);
Factory factory = (Factory) OBJENESIS.newInstance(enhancer.createClass());
factory.setCallbacks(new Callback[] { interceptor });