JDK-8029240 : Default methods not always visible under -source 7
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-11-27
  • Updated: 2014-08-05
  • Resolved: 2013-12-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u20Fixed 9 b01Fixed
Related Reports
Relates :  
Relates :  
Description
Consider an interface available to pre-8 programs that changes an abstract method to a default method, and adds another default method:

interface I { void m(); }
// becomes
interface I {
  default void m() {}
  default void n() {}
}

(The method n is just for illustration -- there's no way to tell the difference between an old method that was converted to a default method and a fresh default method.)

Also consider three subtypes of I:
interface J extends I {}
abstract class A implements I {}
class B implements I {}

javac should be able to cleanly handle the following scenarios:

1) Legacy implementations of I, J, A, and B still compile under -source 7 and don't need to implement I.n

class C1 implements I { @Override public void m() {} }
// Expected: success
// Actual: success

class C2 implements J { @Override public void m() {} }
// Expected: success
// Actual: success

class C3 extends A { @Override public void m() {} }
// Expected: success
// Actual: success

class C4 extends B { @Override public void m() {} }
// Expected: success
// Actual: success

2) Legacy invocations of m via I, J, A, and B still compile under -source 7

class Test {
  public static void test(I i, J j, A a, B b) {
    i.m();
    j.m();
    a.m();
    b.m();
  }
}
// Expected: success
// Actual: error -- B does not have an m method

3) Super invocations of m via A and B compile under -source 7:

class SubA extends A {
  public void test() { super.m(); }
}
// Expected: success
// Actual: success

class SubB extends B {
  public void test() { super.m(); }
}
// Expected: success
// Actual: error -- B does not have an m method

Comments
Release team: Approved for deferral.
06-12-2013

8-defer-request: This issue is not a show-stopper we think that it's better to wait till 8u20 to fix this.
02-12-2013

To clarify where class B might realistically come from, perhaps it used to look like this: class B implements I { public void m() {} } But was refactored (in the library) when the default was added to I: class B implements I {}
27-11-2013