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="");
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="");
- relates to
-
JDK-6975231 Regression test for 6881115 is failing with compiler output not matching expected output
- Closed
-
JDK-6976649 javac does not enforce required annotation elements in arrays
- Closed
-
JDK-7042623 Regression: javac silently crash when attributing non-existent annotation
- Closed