Springの宣言型トランザクション(@Transactionalアノテーション)を「aspectj」モードで使用しています。ほとんどの場合、正常に機能しますが、機能しない場合もあります。私たちはそれを呼ぶことができますLang
(それが実際に呼ばれているものだからです)。
ロードタイムウィーバーに問題を特定することができました。aop.xmlでデバッグと詳細ログをオンにすることで、織り込まれているすべてのクラスが一覧表示されます。問題のあるクラスLang
は、実際にはログにまったく記載されていません。
次に、の先頭にブレークポイントを設定し、クラスがロードされるLang
ときにEclipseがスレッドを一時停止するようにします。Lang
このブレークポイントは、LTWが他のクラスを織り込んでいるときにヒットします。したがって、ウィービングLang
を試みて失敗し、それを出力しないか、または他のクラスに、Lang
実際にウィービングする機会を得る前にロードを強制する参照があると推測しています。
ただし、これを小規模に再現できないため、これをデバッグし続ける方法がわかりません。続行する方法について何か提案はありますか?
更新:他の手がかりも歓迎します。たとえば、LTWは実際にどのように機能しますか?たくさんの魔法が起こっているようです。LTWからさらに多くのデバッグ出力を取得するためのオプションはありますか?私は現在持っています:
<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
私は前にそれについて言及するのを忘れました:春のエージェントはLTWを可能にするために使用されています、すなわちInstrumentationLoadTimeWeaver
。
Andy Clementの提案に基づいて、AspectJトランスフォーマーがクラスを通過したことがあるかどうかを調べることにしました。にブレークポイントを設定すると、他のクラス(JettyのWebAppClassLoaderのインスタンス)と同じクラスローダーによってロードされているにもかかわらずClassPreProcessorAgent.transform(..)
、クラスがそのメソッドに到達することはないようです。Lang
次に、にブレークポイントを設定しましたInstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..)
。その1つでさえもヒットしませんLang
。また、使用しているクラスローダーに関係なく、ロードされたすべてのクラスに対してメソッドを呼び出す必要があると思います。これは次のようになり始めています:
- デバッグに問題があります。Eclipse
Lang
がロードしていると報告したときにロードされていない可能性があります - Javaのバグ?とてつもない、しかし私はそれが起こると思います。
次の手がかり:電源を入れたところ、トランスがインストルメンテーションに追加される前に、ロードが時期尚早である-verbose:class
ように見えます。奇妙なことに、私のEclipseブレークポイントはこの読み込みをキャッチしません。Lang
これは、春が新たな容疑者であることを意味します。ConfigurationClassPostProcessor
クラスをロードしてそれらを検査する処理が行われているようです。これは私の問題に関連している可能性があります。
の次の行ConfigurationClassBeanDefinitionReader
により、Lang
クラスが読み取られます。
else if (metadata.isAnnotated(Component.class.getName()) ||
metadata.hasAnnotatedMethods(Bean.class.getName())) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
return true;
}
特に、そのクラスのすべてのメソッドのすべてのパラメータクラスをロードするクラスをmetadata.hasAnnotatedMethods()
呼び出します。getDeclaredMethods()
クラスはアンロードされるはずなので、これで問題は解決しないのではないかと思います。不明な理由でJVMがクラスインスタンスをキャッシュしている可能性がありますか?