Community
Participate
Working Groups
The following code example compiles, but when executed it throws: Exception in thread "main" java.lang.NoSuchMethodError: NoSuchMethodError.MyListImpl.get()Ljava/lang/String; at NoSuchMethodError.StringListImpl.get(StringListImpl.java:1) at NoSuchMethodError.Test.main(Test.java:13) ----------------------- public interface Foo { Object get(); } public interface MyList<F> extends Foo { public F get(); } public class MyListImpl<G> implements MyList<G> { public G get() { return null; } } public interface StringList extends MyList<String> {} public class StringListImpl extends MyListImpl<String> implements StringList {} public class Test { public static void main(String[] args) { Foo f = new StringListImpl(); } }
Cannot reproduce. Works fine in latest.
I tested with latest, same problem, for me it does not work. I'm using 3.1 M4 under Linux with jdt.core HEAD and Java version 1.5.0_01.
3.1M4 is by no mean the latest, try 3.1M5 or better; it should be fixed. We corrected numerous compiler issues in between M4 and M5, and this one issue got addressed during this process.
OK. Sorry I must have missed M5 (I usually do not miss any update ;-) ). Nevertheless the problem is still there, with M5a and jdt.core HEAD. Would it help if I post the .class files?
Does the problem persist if you do a clean rebuild ? When trying your testcase, I had all the types grouped in a single source file and it did work just fine.
A clean rebuild does not help. I also tested it with all classes in one file, same problem.
Actually, I was able to reproduce by first adding an invocation of #get() in the testcase. interface Foo { Object get(); } interface MyList<F> extends Foo { public F get(); } class MyListImpl<G> implements MyList<G> { public G get() { return null; } } interface StringList extends MyList<String> {} class StringListImpl extends MyListImpl<String> implements StringList {} public class X { public static void main(String[] args) { Foo f = new StringListImpl(); f.get(); } }
Oh no. Damn. I am so stupid. Yes I forgot this line. Sorry! Meanwhile, I run javap on the class files generated by Eclipse and compared them to the class files generated by javac 1.5. Except one file all files have been pretty identical. But I found an important difference in StringListImpl.class: ---- snip ---- --- Javac.disasm 2005-03-08 11:50:35.130127224 +0100 +++ Eclipse.disasm 2005-03-08 11:50:31.492680200 +0100 @@ -3,8 +3,14 @@ testnosuchmethod.allinonefile.StringListImpl(); Code: 0: aload_0 - 1: invokespecial #1; //Method testnosuchmethod/allinonefile/MyListImpl."<init>":()V + 1: invokespecial #11; //Method testnosuchmethod/allinonefile/MyListImpl."<init>":()V 4: return +public java.lang.Object get(); + Code: + 0: aload_0 + 1: invokevirtual #20; //Method testnosuchmethod/allinonefile/MyListImpl.get:()Ljava/lang/String; + 4: areturn + }
No problem, glad you insisted. Problem comes from the fact we introduced a bridge method, where none is needed. As the exception says, the bridge method is targeting an undefined method, which only exists in the compiler typesystem, but not on disk.
Added GenericTypeTest#test556. Fixed by ensuring using the target original signature when bridging, as opposed to using current method.
Kent - pls double check this fix
Great, it works now! Thanks!
Verified in I20050330-0500