932224924qqcom
932224924qqcom

Reputation: 1

How to visit annotation inside method in ASM

guys, I can not visit local variable annotation use asm MethodVisitor, I do not know how to do, please help me, I want get the value "in method", but the MethodVisitor visitLocalVariableAnnotation() method does not called by the ASM logic, here is my code:

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.LOCAL_VARIABLE})
public @interface SendEvent {
    String value() default "hello every";
}


public class AnnotationTest {
    public void test() {
        @SendEvent(value = "in method")
        EventBase base =  new EventBase();
    }
}

public class AsmMethodVisitor extends MethodVisitor implements Opcodes {

    public AsmMethodVisitor(MethodVisitor methodVisitor) {
        super(ASM7, methodVisitor);
        System.out.println("== AsmMethodVisitor");
    }

    @Override
    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) {
        System.out.println("== visitLocalVariableAnnotation");
        return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
    }
}

Upvotes: 0

Views: 837

Answers (1)

Johannes Kuhn
Johannes Kuhn

Reputation: 15163

This is expected, as per JLS 9.6.4.2 this information is simply not retained in the class file:

9.6.4.2. @Retention

Annotations may be present only in source code, or they may be present in the binary form of a class or interface. An annotation that is present in the binary form may or may not be available at run time via the reflection libraries of the Java SE Platform. The annotation type java.lang.annotation.Retention is used to choose among these possibilities.

If an annotation a corresponds to a type T, and T has a (meta-)annotation m that corresponds to java.lang.annotation.Retention, then:

  • If m has an element whose value is java.lang.annotation.RetentionPolicy.SOURCE, then a Java compiler must ensure that a is not present in the binary representation of the class or interface in which a appears.

  • If m has an element whose value is java.lang.annotation.RetentionPolicy.CLASS or java.lang.annotation.RetentionPolicy.RUNTIME, then a Java compiler must ensure that a is represented in the binary representation of the class or interface in which a appears, unless a annotates a local variable declaration or a annotates a formal parameter declaration of a lambda expression.

    An annotation on the declaration of a local variable, or on the declaration of a formal parameter of a lambda expression, is never retained in the binary representation. In contrast, an annotation on the type of a local variable, or on the type of a formal parameter of a lambda expression, is retained in the binary representation if the annotation type specifies a suitable retention policy.

    Note that it is not illegal for an annotation type to be meta-annotated with @Target(java.lang.annotation.ElementType.LOCAL_VARIABLE) and @Retention(java.lang.annotation.RetentionPolicy.CLASS) or @Retention(java.lang.annotation.RetentionPolicy.RUNTIME).

    If m has an element whose value is java.lang.annotation.RetentionPolicy.RUNTIME, the reflection libraries of the Java SE Platform must make a available at run time.

If T does not have a (meta-)annotation m that corresponds to java.lang.annotation.Retention, then a Java compiler must treat T as if it does have such a meta-annotation m with an element whose value is java.lang.annotation.RetentionPolicy.CLASS.

(emphasis mine)

ASM can simply not emit events for information that is not present.

Upvotes: 2

Related Questions