Re: Strange runtime error: AbstractMethodError
"Oliver Wong" <owong@castortech.com> wrote in message
news:7Oryh.94111$vT5.1685226@wagner.videotron.net...
After a bit for trimming, I've formed an SSCCE that doesn't require any
external libraries:
<SSCCE>
interface Root {
public Root someMethod();
}
interface Intermediary extends Root {
public Leaf someMethod();
}
class Leaf implements Intermediary {
@Override
public Leaf someMethod() {
return null;
}
}
public class BugTest {
public static void main(String[] args) {
Leaf leafReference = new Leaf();
leafReference.someMethod();
Root rootReference = leafReference;
rootReference.someMethod(); /* throws error */
}
}
</SSCCE>
Thank you, everyone, for your help.
I made the change Chris suggested, and added a System.out.println("Got
here") to Leaf for debugging purposes.
If I take out the @Override annotation, I get the exact same result with
Eclipse's compiler: No compile errors, but the AbstractMethodError at
runtime. However if I compile the original source code (with the @Override
annotation, and with the system.out.println) using Sun's javac compiler, it
compiles fine, and runs fine (the message is printed out twice as expected).
So it sounds like this is a bug in Eclipse's compiler. I did a
disassembly of both the javac classes and the eclipsec classes, and all the
files are identical except for Leaf.class.
Here's the javac version:
<disassembly>
Compiled from "BugTest.java"
class Leaf extends java.lang.Object implements Intermediary{
Leaf();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public Leaf someMethod();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String Yup, we're here.
5: invokevirtual #4; //Method
java/io/PrintStream.println:(Ljava/lang/String;)V
8: aconst_null
9: areturn
public Root someMethod();
Code:
0: aload_0
1: invokevirtual #5; //Method someMethod:()LLeaf;
4: areturn
}
</disassembly>
And here's the Eclipse version:
<disassembly>
Compiled from "BugTest.java"
class Leaf extends java.lang.Object implements Intermediary{
Leaf();
Code:
0: aload_0
1: invokespecial #10; //Method java/lang/Object."<init>":()V
4: return
public Leaf someMethod();
Code:
0: getstatic #18; //Field
java/lang/System.out:Ljava/io/PrintStream;
3: ldc #24; //String Yup, we're here.
5: invokevirtual #26; //Method
java/io/PrintStream.println:(Ljava/lang/String;)V
8: aconst_null
9: areturn
}
</disassembly>
The main difference being the lack of "public Root someMethod();" within
Eclipse's version.
I filed this as a bug with Eclipse:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=173477
- Oliver