Preface: I want to create a proxy of an existed proxy (Using cglib package in spring) , like when I call the original method class both methods of both proxies called first. Does it make any sense at all? or is it possible?
Problem: When I'm creating the second enhancer
, i get the
java.lang.ClassFormatError-->Duplicate method name "newInstance" with signature "
exception.
public class OriginalClass {
public void print(){
System.out.println("MAIN METHOD");
}
}
public class Main {
public static void main(String[] args) {
//Create First Proxy
Enhancer firstEnhancer= new Enhancer();
firstEnhancer.setSuperclass(OriginalClass.class);
firstEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT FIRST PROXY");
return methodProxy.invokeSuper(o, objects);
});
OriginalClass firstProxy = (OriginalClass) firstEnhancer.create();
//Create Second Proxy
Enhancer secondEnhancer= new Enhancer();
secondEnhancer.setSuperclass(firstProxy.getClass());
secondEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT SECOND PROXY");
return methodProxy.invokeSuper(o, objects);
});
//Getting Exception on this line
OriginalClass secondProxy = (OriginalClass) secondEnhancer.create();
//Call
secondProxy.print();
}
}
METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD
Caused by: java.lang.ClassFormatError: Duplicate method name "newInstance" with signature "([Lorg.springframework.cglib.proxy.Callback;)Ljava.lang.Object;" in class file com/test/OriginalClass$$EnhancerByCGLIB$$37b306ed$$EnhancerByCGLIB$$15133919
I want to wrap a proxy on all beans that have been proxied by spring, using BeanPostProcessors
and cglib
. For example, I want to wrap a proxy on all @transactional
methods (log before and after the transactions).
Update: I prefer to create proxies, not AOPs.(AOP is itself a proxy)
I've found working soultion, it works when used methodProxy.invoke()
instead of methodProxy.invokeSuper()
in the second enhancer, also the firstProxy
need to be passed to the invocation instead of the o
object and the superClass is set to the original one, that doesn't have the newInstance method:
public class Test {
public static void main(String[] args) {
//Create First Proxy
Enhancer firstEnhancer= new Enhancer();
firstEnhancer.setSuperclass(OriginalClass.class);
firstEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT FIRST PROXY");
return methodProxy.invokeSuper(o, objects);
});
OriginalClass firstProxy = (OriginalClass) firstEnhancer.create();
//Create Second Proxy
Enhancer secondEnhancer= new Enhancer();
secondEnhancer.setSuperclass(firstProxy.getClass().getSuperclass());
// secondEnhancer.setSuperclass(OriginalClass.class);
secondEnhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("METHOD INTERCEPTOR AT SECOND PROXY");
return methodProxy.invoke(firstProxy, objects);
});
//Getting Exception on this line
OriginalClass secondProxy = (OriginalClass) secondEnhancer.create();
//Call
secondProxy.print();
}
}
result:
METHOD INTERCEPTOR AT SECOND PROXY
METHOD INTERCEPTOR AT FIRST PROXY
MAIN METHOD