Defaut methods are not visible if -source 1.7 is set

Brian Goetz brian.goetz at oracle.com
Tue Oct 29 10:48:53 PDT 2013


We discussed this extensively at some point; its not as simple as this, 
though I admit the details are paging in slowly.

IIRC, the root problem is this: you have a class

class Foo extends List { }

that you want to compile with the 1.8 javac but with -source 1.7.  What 
could happen?

1.  You could fail to compile, because the supertype uses language/VM 
features you don't support.  This would be not very nice.

2.  You could force the user to implement the default methods, since we 
can't assume they're inherited.  This is also not very nice.

3.  We could ignore them.

The root problem is that -source 1.7 still exposes 1.8 libraries to the 
compilation, which is just wrong.  What should happen is we should be 
compiling with the fictitious -platform 1.7, which not only enforces the 
1.7 language level, but also puts the 1.7 JDK classes on the 
bootclasspath.

Eventually, modularity was supposed help here.  At the time, (3) seemed 
the least bad alternative.  But this is indeed a problem for methods 
that acquire defaults.

> spec shoud be changed to say that adding a default implementation
> is not a compatible change

There's no way we're doing this to work around a tooling bug.


On 10/29/2013 1:26 PM, Remi Forax wrote:
> This is from enhanced-metadata-spec-discuss mailing list
> but I think this issue can interest this audience because it seems
> that javac doesn't respect the spec we have drafted or the spec has
> changed without me noticing it.
> Anyway there is a discrepancy somewhere.
>
>  From Joe Darcy:
>
>>> Wouldn't this risk the same issues as when we turned
>>> isAnnotationPresent() into a default?
>>>
>>>
>>
>> No; we don't have the same hazard here as with isAnnotationPresent.
>> The issue we ran into with making isAnnotationPresent a default method
>> was that isAnnotationPresent was part of the original AnnotatedElement
>> interface defined way back in Java SE 5. In implementation decision in
>> javac did not expose the existence of default methods to code being
>> compiled under source levels less than 8. That is a pragmatic choice
>> and usually gives the desired result, but not in this case.
>>
>
> So it seems that javac 8 doesn't see default methods if source level is
> 1.7 (-source 1.7)
> and as Joe notice this hamper to transform any existing abstract method
> to a default method.
>
> I'm pretty sure that we have talked about that and said that adding
> default to a method should be
> source compatible when we have discussed about Iterator.remove.
> Otherwise it goes against the intuition that providing a body to an
> existing abstract method is harmless.
>
> So either javac8 implementation is not correct (BTW, javac7 see default
> methods)
> or the spec shoud be changed to say that adding a default implementation
> is not a compatible change
> and Iterator.remove should be re-abstracted.
>
> regards,
> Rémi
>


More information about the lambda-spec-experts mailing list