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
にアクセスしようとすると、Javassist はデフォルト値がないことを教えてくれます。は?value()
@XmlJavaTypeAdapters
言い換えれば、それで問題ありませんが (実際にはありません)、希望していた長さ 0 の配列を指定しました (つまり、既定値は使用しないでください。代わりに、明示的に指定した長さ 0 の配列を使用する必要があります)。 ):
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 でこれを達成する方法がわかりません。いつものように、すべての助けに感謝します。