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

suzuki_su [E-MAIL ADDRESS DELETED]
2013年 4月 2日 (火) 22:37:42 JST


小林さん

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

でやったのですが、インタフェイスに記載があるメソッドしか出ませんでしたので、
AuthenticationServiceImpl.class.getMethods()
で取得しました

以下のようになります。

TOMCAT OK_PATTERN(コンパイルはjavac 1.5.0_22 sun(oracle))
public int AbstractAuthenticateService.authenticate(HogeBase,FooBase) - isBridge:false - isSynthetic:false
public volatile int AuthenticationServiceImpl.authenticate(Hoge,Foo) - isBridge:true - isSynthetic:true

WAS7 jar ERROR_PATTERN (war/jarの作成自体はmvnでやっております。javacもsun(oracle)です)
public int AbstractAuthenticateService.authenticate(HogeBase,FooBase) - isBridge:false - isSynthetic:false
public abstract AuthenticationService.authenticate(Hoge,Foo) - isBridge:false - isSynthetic:false

WAS7 classe OK_PATTERN (TOMCATで利用している該当のclassをコピーしています)
public int AbstractAuthenticateService.authenticate(HogeBase,FooBase) - isBridge:false - isSynthetic:false
public int AuthenticationServiceImpl.authenticate(Hoge,Foo) - isBridge:true - isSynthetic:true

名前が複雑で申し訳ありませんが、
AuthenticateServiceはInterfaceでSmartDeploy対象ではありません。authenticate(HogeBase,FooBase)が定義されてます
AbstractAuthenticateServiceはAuthenticateServiceの実装で、authenticate(HogeBase,FooBase)を実装しているAbstraceClassです。SmartDeploy対象ではありません。

AuthenticationServiceは、InterfaceでSmartDeploy対象です。authenticate(Hoge,Foo)が定義されています
AuthenticationServiceImplは実装クラスで、SmartDeploy対象です。
親はAbstractAuthenticateServiceで、AuthenticationServiceを実装していますが、
親のAbstractAuthenticateServiceで、authenticate(HogeBase,FooBase)が実装されているので、
authenticate(HogeBase,FooBase)の実装はありません。
他残りのauthenticate(Hoge,Foo)から呼ばれるメソッドのみを実装しています。

認証処理の実装でして、
AbstractAuthenticateServiceのauthenticate(HogeBase,FooBase)はテンプレートメソッドで、
パスワードをチェックするとか、認証OKの際の処理を行うとか処理のストーリーだけ定義してあり、
AuthenticationServiceImplで実際のパスワードをチェックする処理の定義が行われています。
AbstractAuthenticateServiceでは、
abstract int checkPassword(HogeBase,FooBase)が定義されており、
AuthenticationServiceImplでは、
int checkPassword(Hoge,Foo)と実装しています




2013/04/02 21:49:26 suzuki_su <suzuki_su @ worksap.co.jp> wrote.
> 小林さん
> 
> お世話になっております。鈴木です。
> 
> こちらでの調査状況を共有します。
> ちょうど同じ所らへんにいました。
> 調査としては、AopProxyのsetupAspectsをdebugしました。
> 
> > ・int authenticate(Object input, Object operator)
> > ・int authenticate(Hoge input, Foo operator)
> は一応上限がありますので
> ・int authenticate(BaseHoge input, BaseFoo operator)
> ・int authenticate(Hoge input, Foo operator)
> となっておりました。
> 
> 問題が無いパターン(classes配下)
> 
> int authenticate(BaseHoge input, BaseFoo operator)
> setupAspectsの中で、setInterceptor
> 
> int authenticate(Hoge input, Foo operator)
> setupAspectsの中で、最初のcontinueに進みます。
> MethodUtil.isBridgeMethod(method) || MethodUtil.isSyntheticMethod(method)
> の部分です
> 
> エラーで落ちるパターン(jarの中)
> 
> int authenticate(BaseHoge input, BaseFoo operator)
> setupAspectsの中で、setInterceptorに進みます
> 
> int authenticate(Hoge input, Foo operator)
> setupAspectsの中で、setInterceptorに進みます
> 
> > とりあえず、WAS7 (Jar の場合と WEB-INF/classes の場合)
> > および Tomcat それぞれについて、AuthenticationService の
> > Class から getMethods() して、各メソッドの isBridge() と
> > isSynthetic() の結果をログ出力してもらえますか?
> 
> これから取りますの。コンパイラの件を含め、しばしお待ち下さい。
> 
> 以上です
> 
> 
> 2013/04/02 21:30:01 Koichi Kobayashi <koichik @ improvement.jp> wrote.
> > 小林 (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 mailing list
> > Seasar-user @ ml.seasar.org
> > https://ml.seasar.org/mailman/listinfo/seasar-user
> > 
> 
> 
> _______________________________________________
> Seasar-user mailing list
> Seasar-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-user
> 


--------------------------------------

WORKS APPLICATIONS

               鈴木 順(Sunao Suzuki)

 EXT    : 3079
 E-Mail : suzuki_su @ worksap.co.jp

--------------------------------------


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