JDK-8027228 : AbstractMethodError expected rather than IncompatibleClassChangeError for invocation on abstract method on iface
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2013-10-24
  • Updated: 2013-10-24
  • Resolved: 2013-10-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
hs25Resolved
Related Reports
Duplicate :  
Description
Given the following (indirectly compiled in such a way to avoid errors):

interface J { int m(); }
interface I extends J { default int m() { return J.super.m(); } }
class C implements I {}

C c = new C(); c.m(); // expected: AME; actual: ICCE

An AbstractMethodError is expected but due to recent changes in Hotspot for the support of private methods this has changed to an IncompatibleClassChangeError.

Comments
Attached "testSuperNull_ICCE_or_AME.zip" is a stand alone test case that reproduces the ICCE. The byte code for interface I and J are respectively: interface I extends J SourceFile: "I.java" minor version: 0 major version: 52 flags: ACC_INTERFACE, ACC_ABSTRACT Constant pool: #1 = InterfaceMethodref #4.#11 // J.m:()I #2 = Class #12 // I #3 = Class #13 // java/lang/Object #4 = Class #14 // J #5 = Utf8 m #6 = Utf8 ()I #7 = Utf8 Code #8 = Utf8 LineNumberTable #9 = Utf8 SourceFile #10 = Utf8 I.java #11 = NameAndType #5:#6 // m:()I #12 = Utf8 I #13 = Utf8 java/lang/Object #14 = Utf8 J { public int m(); descriptor: ()I flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // InterfaceMethod J.m:()I 4: ireturn LineNumberTable: line 3: 0 } interface J SourceFile: "J.java" minor version: 0 major version: 52 flags: ACC_INTERFACE, ACC_ABSTRACT Constant pool: #1 = Class #7 // J #2 = Class #8 // java/lang/Object #3 = Utf8 m #4 = Utf8 ()I #5 = Utf8 SourceFile #6 = Utf8 J.java #7 = Utf8 J #8 = Utf8 java/lang/Object { public abstract int m(); descriptor: ()I flags: ACC_PUBLIC, ACC_ABSTRACT } So I is correctly referring to J.m() using CONSTANT_InterfaceMethodref. Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface J, but class was expected at I.m(I.java:3) at IV_C.m(IV_C.java:3) at IV_C.main(IV_C.java:6) The VM appears to be confused and thinks the default method on interface J is a class (static) method: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokespecial.linking-120 ", if the resolved method is a class (static) method, the invokespecial instruction throws an IncompatibleClassChangeError." Rather than: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokespecial.runtime-120 ", if the selected method is abstract, invokespecial throws an AbstractMethodError" AFAICT this situation in SE 7 has not changed for SE 8 with the specification updates of 335 version 0.6.3: http://cr.openjdk.java.net/~dlsmith/jsr335-0.6.3.html#JJVMS-6.5.invokespecial
24-10-2013