Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6522780

javac order of compilation incorrect when enums with interfaces are referenced

XMLWordPrintable

    • 5.0
    • x86
    • windows_xp

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

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: