Question on binary compatibility regarding default methods
Krystal Mok
rednaxelafx at gmail.com
Wed Mar 19 15:33:22 UTC 2014
Hi Rémi,
Great! Thanks a lot for your answer. That's what I'm looking for.
I do remember that at one point there was a piece of code in the VM that
injected bridge methods, but I didn't follow the development of this area
later, so I thought the VM was still doing that, but it isn't. So I was a
bit confused and needed clarification. Now I've got it :-)
Thanks,
Kris
On Wednesday, March 19, 2014, Remi Forax <forax at univ-mlv.fr> wrote:
> On 03/19/2014 12:36 AM, Krystal Mok wrote:
>
>> Hi all,
>>
>> I'm curious about a corner case of binary compatibility with regard to
>> default methods and separate compilation (the source of many evils...).
>> The
>> example is run with JDK 8 build 132.
>>
>> Description:
>>
>> The starting point is that I've got an interface and an implementation
>> class:
>>
>> public interface IFoo<E> {
>> // empty
>> }
>>
>> public class Foo implements IFoo<Foo> {
>> public void bar(Foo o) {
>> System.out.println("Foo.bar(Foo)");
>> }
>> }
>>
>> Both the interface and the implementation are compiled into Class files.
>> Refer to this as ver1.
>> Foo won't have any bridge methods on it at this point.
>>
>> Later on, the interface adds a default method, and is compiled separately,
>> without recompiling the implementation class:
>>
>> public interface IFoo<E> {
>> default void bar(E e) {
>> System.out.println("IFoo.bar(E)");
>> }
>> }
>>
>> Refer to this as ver2.
>>
>> Then, another class uses the ver2 interface with the ver1 implementation
>> class:
>>
>> public class Main {
>> public static void main(String[] args) {
>> Foo f = new Foo();
>> f.bar(f); // (1) invokevirtual Foo.bar(Foo)void
>>
>> IFoo<Foo> i = f;
>> i.bar(f); // (2) invokeinterface IFoo.bar(Object)void
>> }
>> }
>>
>> The output at (1) and (2) are:
>> Foo.bar(Foo)
>> IFoo.bar(E)
>>
>> My question is: is this the expected behavior according to the current
>> spec, by design? I suppose it is.
>>
>
> yes
>
>
>> The implementation in HotSpot seems to be only using the erased (name,
>> signature) of bar(Object)void when searching candidates, so naturally it
>> won't find the Foo.bar(Foo), and it can't find a bridge method for that
>> because of separate compilation.
>>
>
> yes,
> as you note to solve this issue you have to teach the VM the precise
> semantics of Java generics.
> The lambda EG has initially though it was a good idea to solve this corner
> case so Keith McGuigan have done the daunting jobs to implement in the VM
> the generation of bridges with all the corner cases related to generics
> leading to awful issues like the fact that to generate bridges you have to
> load more classes than necessary.
> So we have backpedaled on that point considering that linking the VM
> semantics to the Java type system was wrong and even evil.
>
> It's obvious now and the lambda EG should have been more more clairvoyant
> on that point (sorry Keith).
>
>
>> Thanks,
>> Kris
>>
>
> cheers,
> Rémi
>
>
More information about the jdk8-dev
mailing list