invokespecial of default methods in unrelated interfaces

Daniel Heidinga Daniel_Heidinga at
Thu Jun 27 07:24:24 PDT 2013

> FWIW, I read "immediate supertype of the invoker" as "direct
> superinterface".  In any case, yes, there are two different ways we
> could define the set of valid invokespecial target interfaces.

Thanks for clearing up the terminology.  Using the VM semantics for "direct
superinterface" (ie: in classfile->interfaces[]), is a good approach.

> The details of exactly what JVM 8 binary compatibility looks like
> need to be explored in depth; I'm happy to consider any suggestions
> you may have.
> 2) That said, I do not think we should be trying to enforce the full
> language-level concept of no level skipping.  I'm happy to allow the
> named class to be any direct superinterface of the calling class.
Wearing my implementers hat, I have no objections here - this is certainly
simpler and clearer to both spec and implement.

However, the primary motivator for adding default methods was to enable
interface evolution without breaking existing binaries.  They enable this
goal for Java 8 as it's the first release that will have default methods so
there is no chance of conflict.  Future Java releases may refactor
interface hierarchies, move or add default implementations, which may break
working binaries and prevent users from upgrading.

Binary compatibility brings the discussion full circle back to the issue of
how to resolve default method conflicts.  Up to now, the decision has been
to avoid complex strategies (linearization, recording compile time targets
in the classfile) and just throw AbstractMethodError.

One possibility is to change the binary compatibility rules so that
refactoring interfaces with default methods or adding new default methods
is not binary compatible.  But this contradicts the state goals of
interface evolution.  It becomes a "one shot" thing that can be done for
Java 8 and never again as future changes won't be binary compatible.

A better, but certainly not perfect, answer is to introduce a default
method versioning scheme using a @defaultSince annotation.  In default
conflict cases (both during vtable creation and super sends), resolution
will pick the method with the lowest @defaultSince version.  The lowest
version representing the most likely valid compile time target. Cases where
the conflict methods have the same @defaultSince version will result in an

This requires a consistent versioning scheme so that libraries from
different maintenance domains don't accidentally "under-ride" the original
default target.  For the JDK using the 1.8, 1.9, etc versions will provide
a consistent experience or we may be able to borrow a versioning scheme
from Jigsaw.

Making this system robust may be extremely difficult.  Its primary benefit
is that it provides a clear answer for JDK evolution, but may struggle with
other frameworks versioning.

Binary compatibility is too important to give up, even if it adds
complexity to the VM.  This seems like a necessary tradeoff.


More information about the lambda-spec-observers mailing list