Bug 173477

Summary: Covariant return types and interfaces
Product: [Eclipse Project] JDT Reporter: Oliver Wong <owong>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: VERIFIED DUPLICATE QA Contact:
Severity: blocker    
Priority: P3    
Version: 3.3   
Target Milestone: 3.3 M5   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Oliver Wong CLA 2007-02-08 11:15:07 EST
Build ID: I20061214-1445

Steps To Reproduce:
Compile and run the following code:

interface Root {
  public Root someMethod();
}

interface Intermediary extends Root {
  public Leaf someMethod();
}

class Leaf implements Intermediary {
  @Override
  public Leaf someMethod() {
    System.out.println("Yup, we're here.");
    return null;
  }
}

public class BugTest {
  public static void main(String[] args) {
    Leaf leafReference = new Leaf();
    leafReference.someMethod();
    Root rootReference = leafReference;
    rootReference.someMethod(); /* throws error */
  }
}

More information:
From within Eclipse, the file compiles fine, but if you try to run it, you'll get a runtime error:

Exception in thread "main" java.lang.AbstractMethodError: 
Leaf.someMethod()LRoot;
 at BugTest.main(BugTest.java:21)

However, if you compile this using Sun's javac compiler, it'll run just fine, and print out the message twice, as expected.

A disassembly of the class files reveals that the two compilers differ mainly in the generation of the Leaf.class file. Sun's javac produces the following bytecode:

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

}

While Eclipse's compiler produces the following bytecode:

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

}
Comment 1 Olivier Thomann CLA 2007-02-08 11:22:28 EST
This is fixed using 3.3M5 build.
I am looking for the duplicate.
Comment 2 Olivier Thomann CLA 2007-02-08 11:24:16 EST
Looks like a dup of bug 168331.

*** This bug has been marked as a duplicate of bug 168331 ***
Comment 3 Olivier Thomann CLA 2007-02-08 13:37:46 EST
Added regression test org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest#test121