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