Defaut methods are not visible if -source 1.7 is set

Remi Forax forax at
Tue Oct 29 11:31:08 PDT 2013

On 10/29/2013 06:48 PM, Brian Goetz wrote:
> 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.

There is already a warning for that, if you compile -source 1.7 -target 
1.7 with javac,
you will have a warning saying that you have to set the bootclasspath to 
a 1.7 rt.jar

So given that using -source 1.7 -target 1.7 with the wrong rt.jar is a 
corner case,
I think your solution 2 is a good compromise but 1 is valid too.

> 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.

and the fact that javac7 doesn't work like that.

>> 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