Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cglib Could not support nested proxy? #135

Open
stateIs0 opened this issue Sep 26, 2018 · 3 comments
Open

Cglib Could not support nested proxy? #135

stateIs0 opened this issue Sep 26, 2018 · 3 comments

Comments

@stateIs0
Copy link

Env: JDK1.8
Cglib:Spring 3.2.5

Excetption:

Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
	at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
	at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
	at cn.think.in.java.learing.proxy.Proxy.getProxy(CglibDemo.java:50)
	at cn.think.in.java.learing.proxy.CglibDemo.main(CglibDemo.java:22)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
	... 4 more
Caused by: java.lang.ClassFormatError: Duplicate method name "newInstance" with signature "([Lorg.springframework.cglib.proxy.Callback;)Ljava.lang.Object;" in class file cn/think/in/java/learing/proxy/Target$$EnhancerByCGLIB$$b4f15570
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	... 10 more

Demo:

public class CglibDemo {

    public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./");
        Target t = new Target();
        Target p = Proxy.getProxy(t);
        Target pp = Proxy.getProxy(p);
        pp.hello();

    }

}


class Target {

    void hello() {
        System.out.println("hello targe!");
    }
}

class Proxy {

    private static final Enhancer en = new Enhancer();

    static <T> T getProxy(T origin) {
        en.setSuperclass(origin.getClass());
        en.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects,
                MethodProxy methodProxy) throws Throwable {
                return method.invoke(origin);
            }
        });
        return (T) en.create();
    }
}

please tell me why? thank you very much.

@SylviaLee89
Copy link

I noticed that there is a similar problem at https://github.com/spring-projects/spring-framework. Perhaps we can refer to this issue to find more context about the bug (e.g. the library version since they share org.springframework.cglib libraries and caused by ClassFormatError exception?).

@fsparv
Copy link

fsparv commented Dec 27, 2021

@SylviaLee89 Not really similar. Illegal method is not the same as duplicate method. AFAICT from looking at the error/trace this issue comes up when proxying a proxy, because the proxy code adds a method named newInstance() to the proxy but it already exists if the original was already proxy.

I hit this trying to fudge around the way EasyMock handles Interfaces with default methods to solve an issue in EasierMock ( fsparv/EasierMock#2 ).

      if (interfaceWithDefaults) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Object.class);
        enhancer.setInterfaces(new Class[] {testObjField.getType()});
        enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> proxy.invokeSuper(obj,args));
        Object o1 = enhancer.create();
        type = o1.getClass();
      }
      Factory mock = (Factory) org.easymock.EasyMock.createMock(type);

@fsparv
Copy link

fsparv commented Dec 27, 2021

FWIW in my case I can get past this particular exception because Easymock shades in it's own copy of cglib, and if I depend on cglib original then the method signatures don't overlap because of differing packages for Callback. Other problems arise, but it confirms the nature of the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants