United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6522780 javac order of compilation incorrect when enums with interfaces are referenced
6522780 : javac order of compilation incorrect when enums with interfaces are referenced

Details
Type:
Bug
Submit Date:
2007-02-08
Status:
Open
Updated Date:
2011-09-17
Project Name:
JDK
Resolved Date:
Component:
tools
OS:
windows_xp
Sub-Component:
javac
CPU:
x86
Priority:
P5
Resolution:
Unresolved
Affected Versions:
6
Targeted Versions:

Related Reports

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Given an interface (I) with a method (m), and an enum (E, with constant X) that implements that interface (and thus X provides an implementation for M).
Given another class that references the enum (C).
Given that none of the corresponding class files exist.

1) If C references m on X, javac will not recognize that E needs to be compiled, and will report a "symbol not found" error for the use of m.
2) If C references m on X, but does so after casting X to I, javac will compile E.
3) If C references one of the enum provided methods (such as toString) on X, javac will compile E.
4) If m is also defined as a method on E, either abstract or not, javac will compile E. (This behaviour is regardless of X implementing m or not implementing m.)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
public interface I {
 public String M();
}

public enum E implements I {
 Bob { public String m() { return "bob"; } };
}

public class C {
 public static void main(final String[] args) {
  System.out.println(E.Bob.m());
 }
}

When no class files exist, javac on C produces a "symbol not found" error for m on Bob.

In the following two cases, javac performs as expected:
public class C2 {
 public static void main(final String[] args) {
  System.out.println(E.Bob.toString());
 }
}

public class C3 {
 public static void main(final String[] args) {
  I iBob= E.Bob;
  System.out.println(iBob.m());
 }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected javac to detect that E needed to be compiled when C was being compiled.
See Description and Steps to Reproduce.
ACTUAL -
javac gave a "symbol not found" error.
See Description and Steps to Reproduce.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
in file I.java:
public interface I {
 public String M();
}

in file E.java
public enum E implements I {
 Bob { public String m() { return "bob"; } };
}

in file C.java
public class C {
 public static void main(final String[] args) {
  System.out.println(E.Bob.m());
 }
}

javac C.java. Unknown symbol error on "Bob.m()" will be produced.

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

CUSTOMER SUBMITTED WORKAROUND :
1) Specifically compile E before C;
2) Cast E.Bob to I before invoking m. (see C3 in Steps to Reproduce)
3) Put a duplicate definition of m into E, such that:
public enum E implements I {
 Bob { public String m() { return "bob"; } };
 public abstract String m();
}

                                    

Comments
EVALUATION

Looks like a bug in the original enum implementation and can be
reproduced in JDK 5.0.
                                     
2007-03-21
WORK AROUND

Compile the enum class first.
                                     
2007-03-21



Hardware and Software, Engineered to Work Together