lundi 7 octobre 2019

Java 9+ unable to get annotations of local variables of method

Since Java 9, the way retention works for annotations which have as a target LOCAL_VARIABLE has changed. Now the bytecode representation will hold information about annotated local variables in each method. However, I have been trying to use reflection to find the annotations (or local variables annotated, or their values) with no luck.

Therefore, does anyone have a clue on how to do this or if it is possible? I am using java 11.

As an example, this is my Main class where I try to get the @Parallel annotations from the test method.

public class Main {

public static void main(String[] args) {

    try {
        System.out.println("Main.class.getDeclaredMethod(\"test\").getAnnotations().length = " +
                Main.class.getDeclaredMethod("test").getAnnotations().length);

        System.out.println("Main.class.getDeclaredMethod(\"test\").getDeclaredAnnotations().length = " +
                Main.class.getDeclaredMethod("test").getDeclaredAnnotations().length);

        Annotation annotation = Main.class.getDeclaredMethod("test").getAnnotation(Parallel.class);
        System.out.println("annotation = " + annotation);

    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
}

void test() {
    @Parallel int a = 2;

    @Parallel int b = 4;
}
}

And this is my annotation implementation. I've just added everything as a target since I am only testing it:

@Target({ ElementType.LOCAL_VARIABLE, ElementType.TYPE, ElementType.TYPE_USE, ElementType.TYPE_PARAMETER,
    ElementType.FIELD, ElementType.PARAMETER, ElementType.PACKAGE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {
}

Running javap -l -v -c -s Main.class will show this:

void test();
descriptor: ()V
flags: (0x0000)
Code:
  stack=1, locals=3, args_size=1
     0: iconst_2
     1: istore_1
     2: iconst_4
     3: istore_2
     4: return
  LineNumberTable:
    line 22: 0
    line 24: 2
    line 25: 4
  RuntimeVisibleTypeAnnotations:
    0: #27(): LOCAL_VARIABLE, {start_pc=2, length=3, index=1}
      Parallel
    1: #27(): LOCAL_VARIABLE, {start_pc=4, length=1, index=2}
      Parallel

It's clear that information about the annotations on the local variables is there, I just don't know if reflection is able retrieve it (or if there's any other way to get it at runtime)





Aucun commentaire:

Enregistrer un commentaire