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

javac permits nested anno w/o mandatory attrs => IncompleteAnnotationException

XMLWordPrintable

    • b109
    • x86
    • linux
    • Verified

      FULL PRODUCT VERSION :
      java version "1.6.0_15"
      Java(TM) SE Runtime Environment (build 1.6.0_15-b03)
      Java HotSpot(TM) Server VM (build 14.1-b02, mixed mode)

      (also reproducible in JDK 7 "m3" ~ b59)

      ADDITIONAL OS VERSION INFORMATION :
      Linux ... 2.6.28-15-generic #49-Ubuntu SMP Tue Aug 18 18:40:08 UTC 2009 i686 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      javac permits you to define a default value of an annotation method as another annotation which is missing mandatory attributes. You can even use this default value. No warning or error is produced by the compiler. The JVM correctly throws an IncompleteAnnotationException, which is only documented to occur when there was a binary mismatch, not the case here.

      I have not yet checked what happens to annotation processors trying to access the missing attribute, but I think javac should be reporting a fatal error before even running processors in this case.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile & run the test program.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A compiler error, preferably in line 13 ("default @Child"), at least in line 18 ("@Holder").
      ACTUAL -
      Compiles without warning or error. Exception when run.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      h=@TestAnnoDefault$Holder(child=@TestAnnoDefault$Child())
      h.child=@TestAnnoDefault$Child()
      Exception in thread "main" java.lang.annotation.IncompleteAnnotationException: TestAnnoDefault$Child missing element attr
              at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:53)
              at $Proxy0.attr(Unknown Source)
              at TestAnnoDefault.main(TestAnnoDefault.java:9)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      public class TestAnnoDefault {
          public static void main(String[] args) {
              Holder h = C.class.getAnnotation(Holder.class);
              System.err.println("h=" + h);
              Child c = h.child();
              System.err.println("h.child=" + c);
              System.err.println("h.child.attr=" + c.attr());
          }
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Holder {
              Child child() default @Child;
          }
          public @interface Child {
              String attr();
          }
          @Holder
          public class C {}
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Provide a legal default value, e.g.

      Child child() default @Child(attr="");

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

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: