12

OSGi 4.3+ウィービングフックサービスの使用例はありますか?AspectJ、ASM、JavaAssistはどうですか?誰かが実際にOSGiWeavingHooksを使用していますか?

OSGi Core 5.0.0セクション56.2の例では、実際の織り方を省略し、「最終的な織り方は読者の練習問題として残しています」と述べています。

私の目標は次のとおりです。

  1. フィールド(プリミティブまたはオブジェクト)に配置できるアノテーション(@MyAnnotation)を作成します。
  2. org.osgi.framework.hooks.weaving.WeavingHookを作成して、そのアノテーションを使用してクラスを織ります
  3. ロードタイムウィービングを使用して、そのアノテーションを持つフィールドの変更をポイントカットします
  4. フィールドが変更されたEventAdminイベントを発生させます。
  5. バンドルの配線を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を導入するため、好きではありません。この依存関係は、バンドルの外部で動的に追加および通知する必要があります。

4

2 に答える 2

2

Apache Aries の Proxy モジュールのProxyWeavingHookを見てください。ASM ライブラリを直接使用して、バイトコードをより低レベルに変更します。

于 2013-04-08T08:54:55.927 に答える
0

WeavingAdaptor は、WeavingClassLoader が URLClassLoader から派生することを想定しているため、利用可能な両方のコンストラクターは基本的に最終的に同じことを行います。http://www.slideshare.net/mfrancis/bytecode-weavingをチェックして、BundleWiring を利用してクラスパス URL にアクセスする方法を確認してください。AspectJ ランタイム パッケージを wovenClass.getDynamic'Imports() に追加して、AspectJ の直接参照を回避できます。BundleWiring は、WeavingAdaptor に AspectJ の URL を提供する方法でもあります。

weave フックは、weave メソッド内でのみ動的インポートを使用できると述べているため、acceptClass からの新しいクラスをサポートする方法はないと思います。

于 2013-05-24T06:52:39.477 に答える