OSGi 4.3+ウィービングフックサービスの使用例はありますか?AspectJ、ASM、JavaAssistはどうですか?誰かが実際にOSGiWeavingHooksを使用していますか?
OSGi Core 5.0.0セクション56.2の例では、実際の織り方を省略し、「最終的な織り方は読者の練習問題として残しています」と述べています。
私の目標は次のとおりです。
- フィールド(プリミティブまたはオブジェクト)に配置できるアノテーション(@MyAnnotation)を作成します。
- org.osgi.framework.hooks.weaving.WeavingHookを作成して、そのアノテーションを使用してクラスを織ります
- ロードタイムウィービングを使用して、そのアノテーションを持つフィールドの変更をポイントカットします
- フィールドが変更されたEventAdminイベントを発生させます。
- バンドルの配線をWeavingHookからEventAdminバンドルに動的に更新します。
私の問題は主に#3にあります。
現在、AspectJ WeavingAdaptorを使用してウィービングを実行しようとしていますが、コンストラクター内のjava.net.URL []アスペクトURLがjarまたはディレクトリであると想定しているため、アスペクトライブラリを取り込む際に問題が発生します。バンドルではなく、ファイルシステムで見つけることができます。また、 GeneratedClassHandlerのacceptClass(String name、bytes [])メソッドへのコールバックを介してウィーバーによって生成された新しいクラスを処理する方法がわかりません。
たぶんWeavingAdaptorは私の織りを始めるのに適切な場所ではありませんか?それとも、AspectJを使うべきではないのでしょうか?
MyAnnotation.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
MyWeavingHook.java
public class MyWeavingHook implements WeavingHook {
public class MyWeavingClassloader implements WeavingClassLoader {
private Bundle b;
public MyWeavingClassLoader(Bundle b) {
this.b = b;
}
void acceptClass(java.lang.String name, byte[] bytes) {
//no way to get this back into the woven classes bundle classloader?
}
URL[] getAspectURLs() {
//how do I get a handle to my aspect library that AspectJ can understand?
}
}
public void weave(WovenClass myclass) {
Bundle b = Framework.getBundle(MyWeavingHook.class);
WeavingClassLoader wc = new WeavingClassLoader(b);
WeavingAdaptor w = new WeavingAdaptor(wc);
if (shouldWeave(myclass))
myclass.setBytes(w.weave(myClass.getBytes()));
//should catch exceptions
}
private boolean shouldWeave(WovenClass myclass) {
//not sure of the best logic to pick which classes to weave yet
}
}
MyAspect.aj
privileged aspect MyAspect {
after() : set(* *) && @annotation(MyAnnotation) {
//send EventAdmin event
}
}
MyTestClass.java
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
Spring AOPを使用することもできますが、SpringまたはBlueprintを介してインスタンス化されたBeanだけでなく、すべてのバンドルでこれを機能させたいと考えています。また、Equinox WeavingはまだOSGiウィービングフック仕様を使用していないようで、Equinoxに縛られたくありません。他の何かがうまく機能すれば、私はAspectJを廃棄することに問題はありません。
同様の質問への参照:OSGiを使用しているときにバイトコード操作を行うことは可能ですか?
アップデート:
最終結果は、Equinox Aspectsを使用して、それをKarafにインストールしたところです。3つのバンドル、1つのライブラリ、およびシステムプロパティでした。OSGiウィービングに更新されるか、Equinox Aspectsと同様のAspectJコードを使用するために独自のOSGiウィービングフックを作成するまで、これを使用します。Equinox Aspectsを機能させるために必要なウィービングインジケーターは、ウィービングするバンドルのAspectJRTにrequire-bundle/reexportまたはimport-packageを導入するため、好きではありません。この依存関係は、バンドルの外部で動的に追加および通知する必要があります。