2015-05-27 9 views
2

Я пытаюсь получить аннотацию из метода, но у меня проблемы. То, что я делаю, это загрузить файл jar с помощью URLClassLoader, затем я проверяю аннотации методов в классах в этой банке, используя отражение и Method.getAnnotation.
Проблема, с которой я столкнулся, заключается в том, что метод. Возвращаемое значение возвращает всегда null, даже если существует аннотация (которую мы можем увидеть с помощью метода Method.getAnnotations). Я тестировал ту же процедуру в том же типе аннотаций на классах, которые не загружаются с помощью URLClassLoader, и он отлично работает.
Более подробное исследование показывает, что каноническое имя экземпляра instance.annotationType() и MyAnnotation.class идентично. Однако instance.annotationType(). Equals (MyAnnotation.class) возвращает false. Сам экземпляр, однако, является прокси (com.sun.proxy).Как работать с загрузчиком классов и аннотациями

Есть ли способ получить аннотацию и поля аннотации без значительного количества отражений?

instance.annotationType().getMethod("value").invoke(instance) 

выше будет работать, чтобы получить на поле, и перебирая в результате Method.getAnnotations с сравнения строк на канонические имена получили бы мне аннотацию, но, конечно, есть лучший способ?

Также для образовательной ценности, что вызывает это? Я предполагаю, что это потому, что класс аннотации, загруженный загрузчиком системного класса, как-то отличается от класса аннотации, загруженной загрузчиком класса URL.

+0

Я согласен с вашим Угадай. Существуют два типа MyAnnotation. Чтобы устранить это, убедитесь, что аннотированный класс и аннотация загружены одним и тем же загрузчиком классов. Возможно, это помогает, если ваш пользовательский загрузчик классов использует текущий загрузчик классов как родительский. – CoronA

+0

@CoronA Пользовательский загрузчик классов использует текущий загрузчик классов как родительский. Я не знаю, как обеспечить их загрузку одним и тем же загрузчиком, мне понадобятся дополнительные знания о внутренних компонентах JVM и жизненном цикле этих типов вещей. – kag0

+0

Возможно, вы получаете доступ к своему пользовательскому загрузчику классов. Вместо вызова 'getAnnotation (MyAnnotation.class)' вы можете вызвать 'getAnnotation (customClassLoader.load (« MyAnnotation »))' (с полным именем класса). Перед загрузкой этого класса убедитесь, что MyAnnotation не ссылается. – CoronA

ответ

2

Hacky решение выглядит следующим образом:

Вместо AccessibleObject.getAnnotation (класс annotationClass) используют

private static Annotation getAnnotation(AccessibleObject object, Class annotationClass){ 
    for(Annotation a : object.getAnnotations()){ 
     if(a.annotationType().getCanonicalName().equals(annotationClass.getCanonicalName())) 
      return a; 
    } 
    return null; 
} 

Вместо MyAnnotation.value() использовать

private static Object getAnnotationFieldWithReflection(Annotation annotation, String fieldName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 
    return annotation.annotationType().getMethod(fieldName).invoke(annotation); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^