JDK-8194847 : javac generates bad code for private method in interface super call
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9,9.0.4,10,11
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2018-01-09
  • Updated: 2018-06-04
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.
Other
tbd_minorUnresolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 16.7.0: Mon Nov 13 21:56:25 PST 2017; root:xnu-3789.72.11~1/RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
The following code is compiled fine.

package a;

public class A {
    public static void main(String[] args) {
        new C().test();
    }

    private interface B {
        private void test() {
        }
    }

    static class C implements B {
        void test() {
            B.super.test();
        }
    }
}

But when you try to run this code, you will receive exception:

Exception in thread "main" java.lang.NoSuchFieldError: super
	at a.A$C.test(A.java:15)
	at a.A.main(A.java:5)

Apparently this code should not be compiled, as B.super.test(); construction is improper?


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Take code from description and compile it: javac a/A.java. 
After that run the code:

bash-3.2$ java a.A
Exception in thread "main" java.lang.NoSuchFieldError: super
	at a.A$C.test(A.java:15)
	at a.A.main(A.java:5)

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should not be compiled.
ACTUAL -
The code compiled fine.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NoSuchFieldError: super
	at a.A$C.test(A.java:15)
	at a.A.main(A.java:5)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class A {
    public static void main(String[] args) {
        new C().test();
    }

    private interface B {
        private void test() {
        }
    }

    static class C implements B {
        void test() {
            B.super.test();
        }
    }
}
---------- END SOURCE ----------


Comments
'super.m()' is legal code for invoking private superclass methods (if they are accessible). There is no reason that interfaces should be treated differently than classes. So it's a little surprising that 'I.super.m()' can be used when I.m is private, but there's nothing wrong with it. So (2) is correct: no spec change, just need to fix the code generation.
04-06-2018

@Dan, Assigning to you to have you evaluate the specification change Maurizio refers to. If there is a separate spec bug that already exists or after suitable specification amends are made, this can be reassigned to me for follow up. Thanks.
04-06-2018

Targeting 11 as this requires spec work too.
11-01-2018

Our intent in adding the `I.super.m()` syntax was more towards (1).
11-01-2018

Actually - this has _all_ to do with JDK-8071453 :-). The problem is that the compiler is allowing a default super call on a non-default method. This condition was not possible before since before private methods were added to interfaces, the only kind of instance concrete method available in an interface was, in fact, a default method.
11-01-2018

A big change in b54 is JDK-8071453. The suggested bug JDK-8067886 does not even appear among the ones integrated in b54. That said, I see nothing in JDK-8071453 that could cause such an issue.
11-01-2018

JDK-8067886 is about imports and looks unrelated.
11-01-2018

This issue is not reproducible on 8u162, it is applicable only to 9 and 10. Regression started from 9 ea b54 onwards. 8u162 - Pass //Compilation error 9 ea b53 - Pass //Compilation error 9 ea b54 - Fail //No compilation error, runtime error 9 GA - Fail 9.0.4 - Fail 10 ea b37 - Fail Suspecting this is introduced by JDK-8067886
11-01-2018

Dropping the regression label - this is not a regression; but a possibly unexpected interaction between a new feature (private interface methods) with an existing feature (default method super calls syntax).
11-01-2018

The problem here is that b54 added support for private interface methods. So, while this code was illegal before b54 (as private interface methods were NOT allowed by javac), the code started to compile after b54. There are two possible interpretation of what should happen here: 1) the syntax Type.super.Ident is reserved for default super calls - as such this program should be rejected 2) the syntax Type.super.Ident is reserved for super interface calls - as such this program should be allowed (and the code generation problem fixed) I currently see no basis in the JLS for (1) (see JLS SE 9, section 15.12.3), which seems to suggest that (2) is the way to go. But we need to check as to whether that's deliberate. If (1) is the preferred path, it's likely that a spec change would also be required.
11-01-2018