Bug 83901

Summary: [1.5] AbstractMethodError: Compiler fails to catch missing methods of implemented interface.
Product: [Eclipse Project] JDT Reporter: Matthew Hall <qualidafial>
Component: CoreAssignee: Kent Johnson <kent_johnson>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3    
Version: 3.1   
Target Milestone: 3.1 M5   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on:    
Bug Blocks: 83902    

Description Matthew Hall CLA 2005-01-27 20:51:54 EST
An enum which implements an interface will compile in Eclipse, even if the
methods in the interface are not implemented.  Invoking the interface methods on
one of the enum elements at runtime causes an AbstractMethodError.

The Sun compiler correctly reports that the enum needs to implements methods
from the interface.

Tested against Eclipse 3.1_I20050126-0800

---- EnumImplementsInterfaceTest.java ----

import junit.framework.TestCase;

public class EnumImplementsInterfaceTest extends TestCase {
  public void testImplementsGenericInterface() {
    try {
      E.ITEM.x();
    } catch (AbstractMethodError e) {
      fail();
    }
  }

  static class X {}

  interface I {
    public X x();
  }

  enum E implements I {
    ITEM() {};
    // missing definition of x()
  }
}

---- End of EnumImplementsInterfaceTest.java ----
Comment 1 Matthew Hall CLA 2005-01-27 20:59:15 EST
I have had similar problems lately where I will get AbstractMethodErrors even if
I have declared the abstract method in the enum, and the concrete method for
each element.  Thus far I have not been able to write a test case to capture it
precisely.  Has anybody else run into this problem?
Comment 2 Olivier Thomann CLA 2005-01-28 12:50:16 EST
When the method from the interface is implemented, we still fail with an
AbstractMethodError because we don't tag the enum type as abstract.

Test case:
interface I {
    public Object foo();
}

public enum X implements I {
    ITEM() {
    	public Object foo() {
    		return null;
    	}
    };
	
	public static void main(String[] args) {
		System.out.println(X.ITEM.foo());
	}
}

If I hack the compiler to tag the enum type X as abstract, it runs fine.
Comment 3 Olivier Thomann CLA 2005-01-28 12:53:52 EST
If the enum type implements the interface method, it doesn't need to be tagged
as abstract.

For example, in the following code, X is not abstract.

interface I {
    public Object foo();
}

public enum X implements I {
    ITEM() {
    	public Object foo() {
    		return null;
    	}
    };
	
  	public Object foo() {
   		return "TOTO";
   	}

	public static void main(String[] args) {
		System.out.println(X.ITEM.foo());
	}
}

But if I remove the foo method before the main method, then X is abstract.
Comment 4 Philipe Mulet CLA 2005-02-08 06:07:29 EST
We should indeed reject the following:

interface I {
    public Object foo();
}

public enum X implements I {
    ITEM() {
    };
	public static void main(String[] args) {
		System.out.println(X.ITEM.foo());
	}
}
Comment 5 Kent Johnson CLA 2005-02-11 13:47:45 EST
Added EnumTest test071-075.
Comment 6 David Audel CLA 2005-02-16 09:20:06 EST
Verified in I20050215-2300