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();
}
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();
}