Я использую Javassist для добавления и изменения аннотаций к package-info
«классу».
В некоторых случаях мне приходится иметь дело со следующим крайним случаем.Кто-то (неправильно) указал аннотацию @XmlJavaTypeAdapters
для пакета package-info
, но не предоставил атрибут value
(который определен как обязательный ).Вот так это выглядит так:
@XmlJavaTypeAdapters // XXX incorrect; value() is required, but javac has no problem
package com.foobar;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
В Javassist это происходит немного странно.
javassist.bytecode.annotation.Annotation
, представляющий аннотацию @XmlJavaTypeAdapters
, не имеет значения элемента (getMemberValue("value")
возвращает null
), как и ожидалось.
Конечно, можно добавить value()
значение члена, и вот что я сделал:
if (adaptersAnnotation.getMemberValue("value") == null) {
final ArrayMemberValue amv = new ArrayMemberValue(new AnnotationMemberValue(constantPool), constantPool);
adaptersAnnotation.addMemberValue("value", amv);
annotationsAttribute.addAnnotation(adaptersAnnotation);
}
В кодеВ приведенном выше фрагменте я создал новое значение элемента для хранения массива аннотаций, поскольку атрибут value()
для @XmlJavaTypeAdapters
представляет собой массив @XmlJavaTypeAdapter
.Я указал его тип массива, пытаясь предугадать намерение Zen-подобной документации - кажется, что если вы предоставите еще один MemberValue
, этот MemberValue
каким-то образом будет служить типом массива.В моем случае я хочу, чтобы тип массива был @XmlJavaTypeAdapter
, что является аннотацией, поэтому единственным видом MemberValue
, который показался подходящим, был AnnotationMemberValue
.Поэтому я создал пустой из них и установил его в качестве типа массива.
Это прекрасно работает, пока вы остаетесь "внутри" Javassist.
Однакокажется, что-то пошло не так.Если я прошу Javassist преобразовать все свои собственные аннотации в подлинные Java java.lang.annotation.Annotation
s, то при попытке доступа к атрибуту value()
этой аннотации @XmlJavaTypeAdapters
Javassist скажет мне, что по умолчанию значение отсутствует.Да?
Другими словами, это нормально - действительно, нет - но я указал, что, как я надеялся, был массив нулевой длины (то есть значение по умолчанию не должно использоваться; мое явно указаноВместо этого следует использовать массив нулевой длины):
final List<Object> annotations = java.util.Arrays.asList(packageInfoClass.getAnnotations());
for (final Object a : annotations) {
System.out.println("*** class annotation: " + a); // OK; one of these is @XmlJavaTypeAdapters
System.out.println(" ...of type: " + a.getClass()); // OK; resolves to XmlJavaTypeAdapters
System.out.println(" ...assignable to java.lang.annotation.Annotation? " + java.lang.annotation.Annotation.class.isInstance(a)); // OK; returns true
if (a instanceof XmlJavaTypeAdapters) {
final XmlJavaTypeAdapters x = (XmlJavaTypeAdapters)a;
System.out.println(" ...value: " + java.util.Arrays.asList(x.value())); // XXX x.value() throws an exception
}
}
Так почему же в этом случае Javassist ищет значение по умолчанию?
Моя большая проблема, конечно, это решить (к сожалению, несколькообщий) случай, когда указан @XmlJavaTypeAdapters
без дополнительной информации.Мне нужно добавить value
значение члена, которое может содержать массив аннотаций @XmlJavaTypeAdapter
.Я не могу понять, как сделать это с Javassist.Как всегда, вся помощь приветствуется.