RFR: JDK-8267936: PreserveAllAnnotations option isn't tested

Peter Levart plevart at openjdk.java.net
Wed Jun 2 12:17:30 UTC 2021


On Wed, 2 Jun 2021 11:40:13 GMT, Peter Levart <plevart at openjdk.org> wrote:

>> ...hm, it seems that mere presence of any RUNTIME annotation that was RUNTIME already at the use compile time somehow affects -XX:+PreserveAllAnnotations option so that now RUNTIME annotations that were CLASS annotations at use compile time are not returned. Checking VM logic...
>
> For example, if I try this:
> 
>     @Retention(CLASS)
>     public @interface AnnA_v1 {}
> 
>     // An alternative version of AnnA_v1 with RUNTIME retention instead.
>     // Used to simulate separate compilation (see AltClassLoader below).
>     @Retention(RUNTIME)
>     public @interface AnnA_v2 {}
> 
>     @Retention(RUNTIME)
>     public @interface AnnB {}
> 
>     @AnnA_v1
>     @AnnB
>     public static class TestTask implements Runnable {
>         @Override
>         public void run() {
>             AnnA_v1 ann1 = TestTask.class.getDeclaredAnnotation(AnnA_v1.class);
> 
> ... then `ann1` is not returned, but if I comment out the `@AnnB` annotation use on TestTask, `ann1` is returned.

I think we found a bug here. After all, this endeavor was not in vain. The bug is in AnnotationParser:
https://github.com/openjdk/jdk/blob/6765f902505fbdd02f25b599f942437cd805cad1/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java#L111

You see, the parser reads a 16bit integer from the start of `rawAnnotations` and interprets it as the number of annotations to parse. But OTOH, `rawAnnotations` may in case when `-XX:+PreserveAllAnnotations` was used, contain two concatenated sets of encoded annotations, each starting with its own count of annotations. See how this concatenation is performed here:
https://github.com/openjdk/jdk/blob/6765f902505fbdd02f25b599f942437cd805cad1/src/hotspot/share/classfile/classFileParser.cpp#L3965

The concatenation is simply joining the arrays of u1 elements into a concatenated array. So when both RuntimeVisibleAnnotations and RuntimeInvisibleAnnotations are present (in case -XX:+PreserveAllAnnotations was used), the concatenated array starts with RuntimeVisibleAnnotations followed by RuntimeInvisibleAnnotations.

AnnotationParser should not stop parsing when the 1st loop is finished and the rawAnnotations is not exhausted yet. It should continue with the 2nd round of parsing.

-------------

PR: https://git.openjdk.java.net/jdk/pull/4280


More information about the core-libs-dev mailing list