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