[Seasar-user:21580] Re: AOPで作成されたClassに関して

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2013年 4月 2日 (火) 21:30:01 JST


小林 (koichik) です.

$$MethodInvocation〜 のついたクラスは、文字通り
メソッドを呼び出すためのものなので、AOP が適用される
メソッドの数だけ作られます。

添付の画像では、クラスに対応して作られているのは
3 番目のクラスだけです。

WAS7 で authenticate() メソッドを呼び出すためのクラスが
二つ作られる原因ですが、generics が使われているために
コンパイラは (I と T の上限がないとすると)

・int authenticate(Object input, Object operator)
・int authenticate(Hoge input, Foo operator)

の二つのメソッドを作っているはずで、そのために
S2AOP では Method#isBridge() と isSynthetic() を
使ってチェックしているのですが、それがうまく
いってないものと思われます。
クラスローダよりコンパイラの問題かもしれません。

WAS7 で Jar にパッケージした場合だけ発生するとの
ことですが、パッケージングする際に使われている
コンパイラは IBM JDK でしょうか? それとも Oracle?

.class を WEB-INF/classes に置いた場合というのは、
前述の Jar の中に含まれる .class そのものでしょうか?
それとも Eclipse 等の IDE でコンパイルされたもの?

とりあえず、WAS7 (Jar の場合と WEB-INF/classes の場合)
および Tomcat それぞれについて、AuthenticationService の
Class から getMethods() して、各メソッドの isBridge() と
isSynthetic() の結果をログ出力してもらえますか?

for (Method m : AuthenticationService.class.getMethods()) {
    System.out.printf("%s - isBridge:%b isSynthetic:%b%n", m, m.isBridge(), m.isSynthetic());
}

本来、authenticate(Object, Object) はどちらも true に
なるはずですが、WAS7 + Jar ではそうなっていないかも。
# いずれにせよ、どちらのメソッドも呼び出せるはずなので
# NoSucheMethodError にはならないはずですが。。。


On Tue, 2 Apr 2013 13:48:33 +0900 (JST), suzuki_su <suzuki_su @ worksap.co.jp> wrote:

> お世話になっております。鈴木と申します。
> 
> 添付は、WAS7のクラスローダービューアーの検索結果になります。
> 
> SMART DEPLOY(COOL DEPLOYです)で自動登録され、
>     <component name="serviceCustomizer"
>         class="org.seasar.framework.container.customizer.CustomizerChain">
>         <initMethod name="addAspectCustomizer">
>             <arg>"aop.traceInterceptor"</arg>
>         </initMethod>
>         <initMethod name="addCustomizer">
>             <arg><component class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/></arg>
>         </initMethod>
>     </component>
> と言う定義でカスタマイズされるAuthenticationServiceが、
> 添付のようにクラスローダーに複数個登録されており、
> 実際にはauthenticate5で終わるクラスが使われ、
> NoSucheMethodErrorで落ちます。
> 
> 複雑な継承階層のあるclassで、
> 最上位のインタフェイスでは、
> int authenticate(I input, T operator);
> とGenericで引数のClassが定義されており、
> それが実際の実装クラスで
> int authenticate(Hoge input, Foo operator);
> のように定義されています。
> 実際には、
> int authenticate(Hoge input, Foo operator);
> が無いと言って落ちます
> 
> 
> ちょっとAOP周りに疎いのですが、
> カスタマイズされた結果のクラスはこのように複数個作られるものでしょうか?
> そうなる場合の条件などはありますでしょうか?
> S2の中をデバッグしてみようと思っていますが、
> どの変を見れば良いでしょうか?
> 
> S2.4.44を利用しています。
> WAS7をWINDOWS7(64bit)の上で動かしています。
> 
> 尚、TOMCATではNoSucheMethodErrorは発生していません。
> 
> またAuthenticationServiceはjarの中に含まれてlibの下に配置されておりますが、
> 該当クラスのみ、WEB-INF/classesの下に置いた際にはNoSucheMethodErrorは発生しません。
> クラスローダービューアーで見ると、
> AuthenticationServiceがカスタマイズされたものは複数個登録されていますが、
> authenticate5で終わるものはなく、authenticate0だけです。
> 実際にauthenticate0が使われています。
> WASのjarクラスローダー絡みの問題なのでは無いかと推測しております。
> 
> 環境は手元にありますので、色々試してみることなどは可能です。
> 
> 以上 分かりにくい問題ですみませんが、どうぞ宜しくお願いします。
> 


-- 
{
  name: "Koichi Kobayashi",
  mail: "koichik @ improvement.jp",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
}



Seasar-user メーリングリストの案内