Bug 87273 - [1.5][compiler] Code with generics compiles, but throws a NoSuchMethodError when executed
Summary: [1.5][compiler] Code with generics compiles, but throws a NoSuchMethodError w...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: Other Linux
: P3 normal (vote)
Target Milestone: 3.1 M6   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-07 10:47 EST by Jan Schäfer CLA
Modified: 2005-03-31 09:51 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Schäfer CLA 2005-03-07 10:47:42 EST
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(); 
    } 
}
Comment 1 Philipe Mulet CLA 2005-03-07 11:15:03 EST
Cannot reproduce. Works fine in latest.
Comment 2 Jan Schäfer CLA 2005-03-07 12:49:51 EST
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. 
Comment 3 Philipe Mulet CLA 2005-03-07 15:05:11 EST
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.
Comment 4 Jan Schäfer CLA 2005-03-08 03:30:11 EST
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? 
Comment 5 Philipe Mulet CLA 2005-03-08 04:04:14 EST
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.
Comment 6 Jan Schäfer CLA 2005-03-08 04:55:44 EST
A clean rebuild does not help. I also tested it with all classes in one file, 
same problem. 
Comment 7 Philipe Mulet CLA 2005-03-08 05:44:43 EST
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();
    } 
}
Comment 8 Jan Schäfer CLA 2005-03-08 05:55:46 EST
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 
+ 
 } 
Comment 9 Philipe Mulet CLA 2005-03-08 06:43:18 EST
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.
Comment 10 Philipe Mulet CLA 2005-03-08 06:46:09 EST
Added GenericTypeTest#test556.
Fixed by ensuring using the target original signature when bridging, as opposed
to using current method.
Comment 11 Philipe Mulet CLA 2005-03-08 06:46:39 EST
Kent - pls double check this fix
Comment 12 Jan Schäfer CLA 2005-03-08 07:08:30 EST
Great, it works now! Thanks! 
Comment 13 David Audel CLA 2005-03-31 09:51:50 EST
Verified in I20050330-0500