oblac / jodd

Jodd! Lightweight. Java. Zero dependencies. Use what you like.
https://jodd.org
BSD 2-Clause "Simplified" License
4.06k stars 724 forks source link

Problem with proxies that use concrete classes with generics as return value #191

Closed wouterv closed 9 years ago

wouterv commented 9 years ago

When there is a method in the proxies interface:

    Bar<Foo> getFoo();

And Bar is a concrete class, there will be an exception (see below). Removing the generic fixes the issue. See below for the test classes

Exception in thread "main" java.lang.NoClassDefFoundError: foo/Bar<foo/Foo>
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2585)
    at java.lang.Class.getConstructor0(Class.java:2885)
    at java.lang.Class.newInstance(Class.java:350)
    at jodd.proxetta.ProxettaBuilder.newInstance(ProxettaBuilder.java:277)
    at foo.TestClass.main(TestClass.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.ClassNotFoundException: foo.Bar<foo.Foo>
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 11 more

Test code:

package foo;

public class Bar<T> {
}
package foo;

public class Foo implements IFoo{

    private String id;

    public String getId() {
        return id;
    }

    @Override
    public Bar<Foo> getFoo() {
        return null;
    }

}
package foo;

public interface IFoo {

    String getId();

    //remove the generic and in the implementing class and it works
    Bar<Foo> getFoo();
}
package foo;

import jodd.proxetta.ProxyAspect;
import jodd.proxetta.advice.DelegateAdvice;
import jodd.proxetta.impl.WrapperProxetta;
import jodd.proxetta.impl.WrapperProxettaBuilder;

public class TestClass {

    public static void main(String[] args) {
        ProxyAspect aspect = new ProxyAspect(DelegateAdvice.class);
        WrapperProxetta proxetta = WrapperProxetta.withAspects(aspect);
        WrapperProxettaBuilder builder = proxetta.builder(Foo.class, IFoo.class);
        builder.newInstance();
    }

}
igr commented 9 years ago

First of all, thank you for reporting and for very detailed tests! That really saved some time on my side and helped me finding the issue faster. You rock!

Huh, this one was not easy :) It happened that we were doing some casting to full signature (that includes generic info) instead just to type name. I am running tests at the moment, so commit will come in few minutes.

Thank you again!

wouterv commented 9 years ago

You're welcome!