Never mind ...

On 2/06/2021 10:47 pm, David Holmes wrote:
On 2/06/2021 10:17 pm, Peter Levart wrote:
On Wed, 2 Jun 2021 11:40:13 GMT, Peter Levart <plev...@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

Two arrays are combined into one array and that is returned. What do you mean by "each starting with its own count" ?? Where is the code that shoves the apparent length into the start of the rawAnnotations byte[] ?

Sorry now I see what happens. We aren't combining two arrays of annotations we're concatenating two streams of byes, each of which represents a set of annotations, starting with the length.

The code that receives this on the JDK side doesn't seem to understand that this is a possibility.

Though maybe this isn't a bug, maybe the AnnotationParser is deliberately ignoring the second byte stream. (Though if it were deliberate there should be some commentary to that affect!)

David

Thanks,
David
-----

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

Reply via email to