JDK-6994109 : static import of nested enum hides interface import
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u18
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2010-10-22
  • Updated: 2013-05-30
  • Resolved: 2013-05-30
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.0.6002]

A DESCRIPTION OF THE PROBLEM :
Compiler javac has problems with nested interfaces, imports and static imports of inner types. When using static imports of inner types a class defines itself, other interfaces used by the nested types aren't honored by the compiler. Despite correct import statements the compiler cannot find types and fails to compile.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start with a package structure of root, root.intf and root.cls.
2. Inside root.intf define an interface Outer, inside of Outer define another interface Inner.
3. Inside root.cls define a class Cls, inside of Cls an enum EN, implementing Inner with at least one enum element, for example E1
4. Inside Cls define an attribute of type Inner and assign it E1 plain (no further qualification)
5. add a static import root.cls.Cls.EN.E1
6. add an import of Inner (root.intf.Outer.Inner)
7. Compile -> error "Inner" cannot be resolved (for example Eclipse compiler behaves as expected and compiles)

If the Outer interface is in the same package as the Cls, it's sufficient to just import Outer and qualify Inner during enum's implementation with Outer.Inner. If they're placed in different packages either the static import must be removed and each occurance of E1 fully qualified with EN.E1 or the implementation must use the fully qualified name of Inner (...implements root.intf.Outer.Inner).
By just importing root.intf.Outer while interfaces and class with enum are in different packages and implementing Outer.Inner for the enum, the compiler error says "package Outer not found".

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compiles fine.
ACTUAL -
Doesn't compile.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
imported type cannot be found

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package root.intf;

public interface Outer {
  public interface Inner {};
}

package root.cls;

import static root.cls.Cls.EN.E1;

import root.intf.Outer.Inner;

public class Cls {
  // compiler fails here, can't find Inner
  enum EN implements Inner {
    E1;
  }

  Inner attribute=E1;
}

package root.cls;

import static root.cls.Cls.EN.E1;

import root.intf.Outer;

public class Cls2 {
  // compiler fails here, too, can't find package Outer
  enum EN implements Outer.Inner {
    E1;
  }

  Inner attribute=E1;
}


---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
package root.cls;

import static root.cls.Cls.EN.E1;

public class Cls {
  // fully qualifying solves the problem
  enum EN implements root.intf.Outer.Inner {
    E1;
  }

  Inner attribute=E1;
}