Thursday, August 26, 2010

A couple of comments on Defender Methods

Brian Goetz has posted version 3 of his proposal "Defender Methods", which is a way of adding methods to existing interfaces without breaking binary compatibility. Generally speaking, I think the idea is sound but I think there are some problems with the proposal in its current form. I would normally post my comments on the proposal to the lambda-dev mailing list, which ensures that any IP embedded in my comments are formally submitted to Oracle's ownership. However, Oracle's recent lawsuit against Google has made it clear that, even though I am a contributor to openjdk7, I do not have a license to Oracle's patents that are necessarily infringed by the use of the openjdk7 source base. This is a very confusing position for the organizer of an open-source effort to take. Rather than continuing to contribute IP directly to the project, I'll post my comments here and contribute them to Oracle once it is clear that I've been granted a license to the patents necessary to use openjdk7.

The latest version of the proposal has added a section on "Binary compatibility" (section 11), but that section fails to address the one binary compatibility issue raised previously: what are the binary compatibility implications of changing the default for a defender method? Since the defender method's default is an implementation detail, such a change should be binary (and source) compatible, but the resolution mechanism (section 3) makes it binary incompatible. The proposal doesn't provide compile-time semantics for invoking an extension method or compile-time rules for when a given class declaration is legal. At the very least there should be rules to ensure that sources that compile cleanly together do not trigger a VM error at runtime due to an ambiguous method invocation. The most natural change of the compile-time rules to match the given runtime resolution rules would make changing the defender method's default a source incompatible change as well (because it could introduce an ambiguity). I believe this undermines the justification for having defender methods out-of-line (section 2). Moreover, the separation forces API designers to create vestigial public API elements (the static extension methods).

These issues can be addressed by (a) having defender method bodies written inline, and (b) rejecting non-abstract class declarations where some defender method does not have a unique default.

I suspect the proposed implementation mechanisms (sections 7 and 8) will be far too expensive compared to existing virtual method calls. For the Interface.super calls (section 7), my suggestion is to extend the VM specification of invokespecial.