Breaking binary compatibility due to adding private method to an interface compiled inconsistently

Georgiy Rakov georgiy.rakov at oracle.com
Mon Oct 17 17:26:19 UTC 2016


Hello Dan,

comment [1] specifies following assertion and a note:

    Adding an 'abstract', ***'private', or 'static'*** method to an
    interface does not break compatibility with preexisting binaries.

    [Note: I believe we can make this assertion because "adding a
    method" means "adding a method that will compile", presumably?
    Private and static methods can introduce errors if a reference like
    I.m()V previously resolved to an abstract/default method in a
    superinterface, and now resolves to the private/static method in I.
    But that new method won't compile if there's a method with a
    matching signature in a superinterface of I.]

Namely, the note reads:

    ... "adding a method" means "adding a method that will compile" ...

It's questionable if this is a valid point since spec should take into 
account that a method added might be resulted from inconsistent 
compilation. For instance:

1. First we compile sources A.java, B.java, Test.java presented below.

    A.java:
    interface A {
         default void same() {}
    }

    B.java:
    interface B extends A {
         //private void same() {}
    }

    Test.java:
    class Test {
         public static void main(String[] argv) {
              B i = new B(){};
              i.same();
         }
    }

2. Then we compile sources A.java, B.java presented below (toggle 
commenting 'same' method in A and B):

    A.java:
    interface A {
         //default void same() {}
    }

    B.java:
    interface B extends A {
         private void same() {}
    }


3. Then we compile source A.java presented below (returning back A class 
file as it resulted from step 1):

    A.java:
    interface A {
         default void same() {}
    }

4. Run Test.main(), this results in a run-time error:

    Exception in thread "main" java.lang.IllegalAccessError: tried to
    access method B.same()V from class Test

So adding a private method seems to cause breaking binary compatibility. 
The change between binaries resulted from step 1 and step 3 is B class 
file with a private method added, the rest of the class files are the same.

Should it be considered as a spec issue?

[1] 
https://bugs.openjdk.java.net/browse/JDK-8072872?focusedCommentId=13610992

Thank you,
Georgiy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20161017/aab73f10/attachment.html>


More information about the compiler-dev mailing list