JDK-7160084 : javac fails to compile an apparently valid class/interface combination
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-04-09
  • Updated: 2015-01-19
  • Resolved: 2012-07-11
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 7 JDK 8
7u40Fixed 8 b43Fixed
Related Reports
Relates :  
Description
SYNOPSIS
--------
javac fails to compile an apparently valid class/interface combination

OPERATING SYSTEMS
-----------------
All

FULL JDK VERSIONS
-----------------
All (tested on latest 5.0, 6, 7 and 8)

PROBLEM DESCRIPTION
-------------------
javac fails to compile a enum type if it implements an interface which contains an enum with the same name as that of the implementor.

In the testcase provided below, interface TestInterface has a enum type "enumA", while the class TestClass also has an enum type "enumA" which implements TestInterface. During compilation, javac appears to encounter a name resolution issue and an error occurs.

The same code compiles with no issues under Eclipse, although this scenario does not seem to be explicitly described in the Java Language Specification.

REPRODUCTION INSTRUCTIONS
-------------------------
1. Create the files as provided below
2. Attempt to compile the class:  javac TestClass.java

Expected behaviour
Class should compile with no errors

Actual behaviour
Compilation fails with the following error:

TestClass.java:4: enumA(java.lang.String) has private access in TestInterface.enumA
        A("AAA");
        ^
1 error

TESTCASE
--------
------------------------------------------------------------------------
TestInterface.java
------------------------------------------------------------------------
public interface TestInterface {
    public enum enumA implements TestInterface {
        I("III");

        private enumA(String s) {
            System.out.println(s);
        }
    }
}

------------------------------------------------------------------------
TestClass.java
------------------------------------------------------------------------
public final class TestClass {
    // This causes an error
    public enum enumA implements TestInterface {
        A("AAA");
       
        private enumA(String s) {
            System.out.println(s);
        }
    }
       
    // This doesn't cause an error
    public enum enumB implements TestInterface {
        B("BBB");
       
        private enumB(String s) {
            System.out.println(s);
        }
    }
}

Comments
EVALUATION Hi David, here's a more detailed analysis on this bug. A source that can be used to reproduce the problem is the following: interface Intf { enum MyEnumA { AA(""); private MyEnumA(String s) { } } } class Test { enum MyEnumA implements Intf { AA(""); private MyEnumA(String s) { } } } When javac compiles this source, it transforms it into the following program (enum are replaced by classes/enum values by static fields): interface Intf { public static class MyEnumA { public static final MyEnumA AA = new MyEnumA(""); private MyEnumA(String s) { } } } class Test { Test() { super(); } static class MyEnumA implements Intf { public static final MyEnumA AA = new MyEnumA(""); private MyEnumA(String s) { } } } Which is an illegal source - we should generate qualified name for enum in synthetized enum fields, so that scoping issues are properly addressed.
31-05-2012

SUGGESTED FIX A webrev of this fix is avalable at the following URL: http://hg.openjdk.java.net/jdk8/tl/langtools/rev/37dc15c68760
31-05-2012