references to non-static types from annotations

Liam Miller-Cushon cushon at google.com
Fri Apr 8 17:35:49 UTC 2016


javac fails to reject references to non-static classes inside annotations,
and instead produces invalid output.

Example:

class Test<T> {
  @Retention(RetentionPolicy.RUNTIME) @interface A { Class<?> value(); }
  @A(I.class) interface C {}
  class I {}
  public static void main(String[] args) {
    System.err.println(Arrays.toString(C.class.getAnnotations()));
  }
}

The reference to I.class in `@A(I.class) interface C {}` refers to the
non-static type Test<T>.I, but the annotation is a static context. The
compiler produces this attribute for the annotation:

$ javap -v -private 'Test$C'
...
   #9 = Utf8               LTest$A;
  #10 = Utf8               value
  #13 = Utf8               LTest<TT;>.I;
...
RuntimeVisibleAnnotations:
  0: #9(#10=c#13)

JVMS 4.7.16.1 requires a class_info_index to be the index of a Utf8_info
representing a return descriptor, and `LTest<TT;>.I;` is not a legal return
descriptor.

The bytecode is rejected when read during reflection, and during subsequent
compilations:

$ javac Test.java && java Test
Exception in thread "main" java.lang.ClassCastException:
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast
to java.lang.Class
at
sun.reflect.annotation.AnnotationParser.toClass(AnnotationParser.java:448)
at
sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:441)

$ javac -implicit:none Other.java
Other.java:1: error: cannot access C
class Other { Class<?> clazz = Test.C.class; }
                                   ^
  bad class file: ./Test$C.class
    undeclared type variable: T
    Please remove or make sure it appears in the correct subdirectory of
the classpath.

Recording that a static context is being entered in HeaderPhase before
calling annotateLater fixes the bug, and doesn't break any existing tests.
The compatibility impact of the fix is minimal: I tried patching javac and
building a large code base, and only found a single instance of the problem.

If the proposed fix sounds reasonable, I'd be happy to clean up the patch
for review.

Thanks,
Liam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160408/56c93d2e/attachment.html>


More information about the compiler-dev mailing list