[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-lambda-spec-observers
Subject:    Re: invokespecial of default methods in unrelated interfaces
From:       Daniel Heidinga <Daniel_Heidinga () ca ! ibm ! com>
Date:       2013-06-27 14:24:24
Message-ID: OFF41174FE.5E1937AC-ON85257B97.004EBBB5-85257B97.004F236C () ca ! ibm ! com
[Download RAW message or body]


> 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 "di=
rect
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 certai=
nly
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 th=
is
goal for Java 8 as it's the first release that will have default method=
s so
there is no chance of conflict.  Future Java releases may refactor
interface hierarchies, move or add default implementations, which may b=
reak
working binaries and prevent users from upgrading.

Binary compatibility brings the discussion full circle back to the issu=
e of
how to resolve default method conflicts.  Up to now, the decision has b=
een
to avoid complex strategies (linearization, recording compile time targ=
ets
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 metho=
ds
is not binary compatible.  But this contradicts the state goals of
interface evolution.  It becomes a "one shot" thing that can be done fo=
r
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), resolutio=
n
will pick the method with the lowest @defaultSince version.  The lowest=

version representing the most likely valid compile time target. Cases w=
here
the conflict methods have the same @defaultSince version will result in=
 an
AbstractMethodError.

This requires a consistent versioning scheme so that libraries from
different maintenance domains don't accidentally "under-ride" the origi=
nal
default target.  For the JDK using the 1.8, 1.9, etc versions will prov=
ide
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 bene=
fit
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.

--Dan=
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic