javareflectionjarurlclassloader

How to get method annotation value


I am writing a plugin for parsing a jar archive, using the url classloader, I get reflective access to the classes of this archive, I have annotation names by which I can find the classes corresponding to them in the bytecode (for obvious reasons, I do not have access to the annotation class itself from the code that is currently parsing this jar), I'm sure there is some dirty trick to do this, please help

for example what i am doing in nutshell:

Path pathToJar = Paths.get("/a/b/c/Application.jar");

List<Class<?>> allJarClasses = loadAllJarClasses(pathToJar);

String annotationName = "MyAnnotation";

getValueFromAnnotationWithName(annotationName, allJarClasses);

---

public String getValueFromAnnotationWithName(String annotationName, List<Class<?>> classes) {
    classes.forEach(cl -> {
        Method[] methods = ...getMethods
        for(Method m : methods) {
            Annotations[] annotations = ...getAnnotations from method
            for (Annotation a: annotations) {
               if (a.annotationType().getName().matches(".*" + annotationName)) {
                     return getValueFromAnnotation("someValueName", a); <- here i need help;
               }
            }
        }
    });
}

Update: i can get values while debugging in intellij idea enter image description here

also if do this:

annotationMethod.toString()

i can get this:

@ru.sparural.kafka.annotation.KafkaSparuralMapping(value="file/create")


Solution

  • Annotation elements are just methods. Meaning you can get the value of an annotation element by invoking a Method on the Annotation instance. For example, say we have the following annotation:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Foo {
    
        String value();
    }
    

    Then we get the value of the value element by doing:

    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    
    @Foo("Hello, World!")
    public class Main {
    
        public static void main(String[] args) throws Exception {
            // Pretending we don't have compile-time access to 'Foo'
            Annotation fooAnnotation = Main.class.getAnnotations()[0];
            Method valueMethod = fooAnnotation.annotationType().getMethod("value");
            Object value = valueMethod.invoke(fooAnnotation);
            System.out.printf("value = '%s'%n", value);
        }
    }
    

    And the output is:

    value = 'Hello, World!'