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

Alex Buckley alex.buckley at oracle.com
Tue Oct 18 22:52:46 UTC 2016


I understand that you're going from executing A.class + B.class + 
Test.class to executing A.class + B.class[MODIFIED] + Test.class. 
However, because B.class[MODIFIED] was produced by a non-trivial 
sequence of recompilations, it's tantamount to a hex-edited version of 
the initial B.class. Ch.13 doesn't describe the binary compatibility of 
hex edits, only the binary compatibility of a single compilable change 
to a single compilation unit. I agree with Dan that the binary 
compatibility of adding a private method to an interface inherently 
assumes you immediately compile the interface.

Alex

On 10/18/2016 7:55 AM, Georgiy Rakov wrote:
> I'd like to emphasize that in this case preexisting binaries supplied to
> JVM during Test.main execution doesn't change and if they don't then,
> according to my understanding, it doesn't matter how the modified B
> class-file was produced.
>
> Thank you,
> Georgiy.
>
> On 17.10.2016 21:15, Alex Buckley wrote:
>> The key phrase is "with preexisting binaries". Given the initial
>> A.class + B.class + Test.class, you get to make ONE change to ONE
>> compilation unit that you recompile independently but inconsistently.
>> The change you would like to make is adding a private method to B, but
>> you can't make that change because of B's superinterface, so no
>> independent recompilation is possible, and the question of whether the
>> change is binary-incompatible is moot.
>>
>> Alex
>>
>> On 10/17/2016 10:26 AM, Georgiy Rakov wrote:
>>> 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.
>


More information about the compiler-dev mailing list