4

私は数日前にこの質問をしましたが、コンパイル時のウィービングを使用してなんとか機能させることができました。

ただし、アプリケーションが実行され、AOP を介して DTO に混在させた toString() メソッドを呼び出すと、以下の例外が発生します。

実行時のクラスパスで AspectJ が必要になるとは思いませんでした。結局、私はコンパイル時のウィービングを使用したので、バイトコードはすでに最終状態になっているはずですよね? AspectJ が実行時に存在すると予想されるのはなぜですか?

java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:506)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)[osgi-3.6.2.R36x_v20110210.jar:]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)[:1.6.0_35]
    ... 51 more

AspectJ に、結果のバイトコードでそれ自体へのすべての参照を削除するように指示する方法はありますか?

注: 私は OSGi 環境で実行していますが、それはまったく関係ありません。

4

2 に答える 2

3

コンパイル時、コンパイル後、またはロード時のウィービングのいずれを使用する場合でも、織り込まれたバイトコードは少数のタイプに依存します。それらを jar で出荷する方が、コンパイルされたすべてのアプリにそれらを生成するよりも簡単であると見なされます。これらのタイプは、小さな jar 'aspectjrt.jar' にカプセル化されています。クラスパスにウィーバー jar またはコンパイラ jar は必要ありません。小さなランタイム jar だけが必要です。いくつかの異なるものが含まれています。

  • アスペクト (@Before、@Aspect) を記述するために使用された可能性のあるランタイム可視アノテーションの定義
  • 問題が発生した場合 (NoAspectBoundException) または言語機能を実装するため (SoftException) の例外タイプ
  • cflow スレッドローカル スタック管理など、一部の言語機能を実装するためのユーティリティ コード。
  • thisJoinPoint のすべてのサポート クラス。thisJoinPoint で getSignature() などにアクセスすると、MemberSignature が返される場合があります。

これらの言語機能を使用していない場合、これらの多くを回避することは可能ですが、NoAspectBoundException は依然として問題になる可能性があります。最も単純な側面でさえ、それに依存します。現時点では、jar 依存関係を完全に回避するコンパイル方法はありません。

依存関係を完全に回避するために追加のコード生成を行うように AspectJ を変更すること可能ですが、それは一般的な要求ではないため、作業は行われていません。

(その環境で使用するための適切な OSGi マニフェスト情報を含む、aspectjrt.jar のビルドがあります。標準ディストリビューションに含まれる jar は、現在そのマニフェストを正しく取得しません)

于 2013-01-17T01:43:43.223 に答える
0

ウィービングがいつ行われたかに関係なく、AspectJ ランタイム ライブラリは引き続き必要になると思います。

于 2013-01-14T15:09:59.453 に答える