invokespecial of default methods in unrelated interfaces

Brian Goetz brian.goetz at oracle.com
Thu Jun 13 11:14:54 PDT 2013


Well, I wouldn't expect C code to be invoked in any case, but a crash is 
probably not a good result.

I believe the intent was to have invokespecial reject an invocation if 
the named class was not an immediate supertype of the invoker.  There 
may also be additional restrictions that the compiler imposes, designed 
to prevent "level skipping" usages, that may or may not need to also be 
enforced by the VM.

On 6/13/2013 1:31 PM, Daniel Heidinga wrote:
> We've put together a defender method test case using invokespecial and
> we'd like some confirmation of our spec interpretation.  The testcase is:
>
> interface A {
> default void m(){ System.out.println("A"); };
> }
> interface B {
> default void m(){ System.out.println("B"); };
> interface C {
> default void m(){ System.out.println("C"); };
> }
> class D implements A, B {
> void m() {
> C.super.m();  // Note, D does not implement C
> }
> public static void main(String[] args) {
> new D().m();
> }
> }
>
> While javac won't compile this, it is legal bytecode (generated with ASM
> because class D is unrelated to interface C).  Executing 'new D().m()'
> unfortunately crashes Hotspot b93.
>
> The lambda changes to the JVM spec for invokespecial indicate 'The named
> method is resolved (5.4.3.3)'.  5.4.3.3 states "Method resolution
> attempts to look up the referenced method in C and its superclasses".
>   As C clearly has an implementation of m(), resolution should succeed
> and C.m() should be called.  (As an aside, there is an issue with
> invokespecial referencing 5.4.3.3 for interface sends: "If C is an
> interface, method resolution throws an IncompatibleClassChangeError.")
>
> Does anyone disagree with this interpretation of the spec?
>
> --Dan
>


More information about the lambda-spec-observers mailing list