runtime failure when "any T" generic method calls another "any T" generic method
Peter Levart
peter.levart at gmail.com
Thu Jan 8 08:09:32 UTC 2015
Hi,
Here's another problem I found:
public class ValhallaTest<any T> {
static <any T> void test2() {
Class<?> clazz = ValhallaTest<T>.class; // line 7
System.out.println("test2 >>> " + clazz);
}
static <any T> void test1() {
Class<?> clazz = ValhallaTest<T>.class;
System.out.println("test1 >>> " + clazz);
ValhallaTest.<T>test2();
}
public static void main(String[] args) {
ValhallaTest.<boolean>test1();
ValhallaTest.<byte>test1();
ValhallaTest.<char>test1();
ValhallaTest.<short>test1();
ValhallaTest.<int>test1();
ValhallaTest.<long>test1();
ValhallaTest.<float>test1();
ValhallaTest.<double>test1();
ValhallaTest.<Object>test1();
ValhallaTest.<String>test1();
}
}
Which prints:
Specializing method ValhallaTest$test1${0=Z}.test1()V with class=[] and
method=[Z]
Specializing ValhallaTest${0=Z}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=Z}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=Z}
Specializing method ValhallaTest$test2${0=Z}.test2()V with class=[] and
method=[Z]
test2 >>> class ValhallaTest${0=Z}
Specializing method ValhallaTest$test1${0=B}.test1()V with class=[] and
method=[B]
Specializing ValhallaTest${0=B}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=B}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=B}
Specializing method ValhallaTest$test2${0=B}.test2()V with class=[] and
method=[B]
test2 >>> class ValhallaTest${0=B}
Specializing method ValhallaTest$test1${0=C}.test1()V with class=[] and
method=[C]
Specializing ValhallaTest${0=C}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=C}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=C}
Specializing method ValhallaTest$test2${0=C}.test2()V with class=[] and
method=[C]
test2 >>> class ValhallaTest${0=C}
Specializing method ValhallaTest$test1${0=S}.test1()V with class=[] and
method=[S]
Specializing ValhallaTest${0=S}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=S}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=S}
Specializing method ValhallaTest$test2${0=S}.test2()V with class=[] and
method=[S]
test2 >>> class ValhallaTest${0=S}
Specializing method ValhallaTest$test1${0=I}.test1()V with class=[] and
method=[I]
Specializing ValhallaTest${0=I}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=I}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=I}
Specializing method ValhallaTest$test2${0=I}.test2()V with class=[] and
method=[I]
test2 >>> class ValhallaTest${0=I}
Specializing method ValhallaTest$test1${0=J}.test1()V with class=[] and
method=[J]
Specializing ValhallaTest${0=J}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=J}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=J}
Specializing method ValhallaTest$test2${0=J}.test2()V with class=[] and
method=[J]
test2 >>> class ValhallaTest${0=J}
Specializing method ValhallaTest$test1${0=F}.test1()V with class=[] and
method=[F]
Specializing ValhallaTest${0=F}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=F}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=F}
Specializing method ValhallaTest$test2${0=F}.test2()V with class=[] and
method=[F]
test2 >>> class ValhallaTest${0=F}
Specializing method ValhallaTest$test1${0=D}.test1()V with class=[] and
method=[D]
Specializing ValhallaTest${0=D}; searching for ValhallaTest.class (not
found)
Specializing ValhallaTest${0=D}; searching for ValhallaTest.class (found)
test1 >>> class ValhallaTest${0=D}
Specializing method ValhallaTest$test2${0=D}.test2()V with class=[] and
method=[D]
test2 >>> class ValhallaTest${0=D}
test1 >>> class ValhallaTest
Specializing method ValhallaTest$test2${}.test2()V with class=[] and
method=[TT;]
Exception in thread "main" java.lang.NoClassDefFoundError: ValhallaTest<TT
at ValhallaTest$test2${}/401625763.test2(ValhallaTest.java:7)
at ValhallaTest.test1(ValhallaTest.java:15)
at ValhallaTest.main(ValhallaTest.java:27)
Caused by: java.lang.ClassNotFoundException: ValhallaTest<TT
at java.net.URLClassLoader.findClass(URLClassLoader.java:451)
at java.lang.ClassLoader.loadClass(ClassLoader.java:426)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317)
at java.lang.ClassLoader.loadClass(ClassLoader.java:359)
... 3 more
Within tes1() method, everything works fine, but cascading call to
test2() fails in line 7 where ValhallaTest<T>.class is evaluated, but
only for reference type T.
Note that there's no specialization for test1() being triggered for
T=reference (which is understandable), but there is a specialization
being triggered for cascaded call to test2() in this case. In my
superficial understanding a call to:
ValhallaTest.<Object>test1();
...is implemented as invokestatic, but a call from test1() to:
ValhallaTest.<T>test2();
...is implemented as invokedynamic. So in case such call comes from
non-specialized test1(), it should be wired directly to the
nonspecialized test2() method, right?
Or, couldn't the call from nonspecialized test1() to .<T>test2() also be
implemented as invokestatic and be converted to invokedynamic only by
specialization?
Regards, Peter
More information about the valhalla-dev
mailing list