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

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2013年 4月 4日 (木) 01:00:00 JST


小林 (koichik) です.

すでに解決しているかもしれませんが一応。

Eclipse と javac で結果が違っているとすると、
大抵は Eclipse のバグ (仕様の範囲を超えて型推論
しちゃう的な) という気がします。

で、[Seasar-user:21583] のこちらですが、

> 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

これを見る限り、二つのメソッドはただのオーバーロードに
なっていて、最初の [Seasar-user:21578] の

> 最上位のインタフェイスでは、
> int authenticate(I input, T operator);
> とGenericで引数のClassが定義されており、
> それが実際の実装クラスで
> int authenticate(Hoge input, Foo operator);
> のように定義されています。

で意図したようにはなっていないと思います。

[Seasar-user:21583] の「名前が複雑で申し訳ありませんが」
以降の文章による説明では型変数がどうなっているか
わからないので、以下のように具体的にそれぞれの
関係を示してもらえますか?

public interface Hoge {...}

public class HogeBase implements Hoge {...}

public interface Foo {...}

public class FooBase implements Foo {...}

public interface AuthenticateService {
  public int authenticate(HogeBase,FooBase);
}

public interface AuthenticationService {
  public int authenticate(Hoge,Foo);
}

public abstract class AbstractAuthenticateService implements AuthenticateService {
  public int authenticate(HogeBase,FooBase) {...}
}

public class AuthenticationServiceImpl extends AbstractAuthenticateService implements AuthenticationService {
  public int authenticate(Hoge,Foo) {...}
}

上記にはまだ型変数が入っていませんが、リフレクションの
結果からはこのようにただのオーバーロードになってますね。



On Wed, 3 Apr 2013 00:04:21 +0900 (JST), suzuki_su <suzuki_su @ worksap.co.jp> wrote:

> 小林さん
> 
> お疲れ様です。鈴木です。
> 
> 役に立たないと思いますが、一応。
> 
> mvn でビルドwarをビルドした際のMETA-INFですが、
> Manifest-Version: 1.0
> Build-Jdk: 1.5.0_12
> Archiver-Version: Plexus Archiver
> Created-By: Apache Maven
> 
> こちらが問題のクラス(AuthenticationServiceとAuthenticationServiceImpl)が入ってるjarをビルドした際のMETA-INFです
> Manifest-Version: 1.0
> Archiver-Version: Plexus Archiver
> Created-By: Apache Maven
> Build-Jdk: 1.5.0_12
> 
> AbstractAuthenticateService/AuthenticateServiceは別のjarに入っています。
> そちらのMETA-INFです。
> Manifest-Version: 1.0
> Archiver-Version: Plexus Archiver
> Created-By: Apache Maven
> Build-Jdk: 1.5.0_20
> 
> 違う端末でBuildしているので、若干JDKのVERSIONが違います。
> これが問題かも明日確認します。
> 
> 以上
> 
> 
> 
> 2013/04/02 23:50:46 suzuki_su <suzuki_su @ worksap.co.jp> wrote.
> > 小林さん
> > 
> > お疲れ様です。鈴木です。
> > 
> > > > TOMCAT OK_PATTERN(コンパイルはjavac 1.5.0_22 sun(oracle))
> > > 
> > > この場合、コンパイルは javac を用いて (コマンドラインで)
> > > 行っていますか? Eclipse でビルドしたものではなく?
> > > # なんとなく、Tomcat は Eclipse 上使ってるのかなと。
> > > # ちなみに Eclipse は独自のコンパイラを持っています。
> > 
> > ご指摘のとおりです。
> > Eclipseのものです。正しく無い情報をすみません。
> > またそれを普通にWAS上のclassesに置いています。
> > Eclipseは、
> > Eclipse Java EE IDE for Web Developers.
> > Version: Indigo Service Release 2
> > Build id: 20120216-1857
> > となっています。
> > 
> > > mvn でビルドしているなら、target/classes 以下に
> > > コンパイルされた .class があるはずですが、それを
> > > WEB-INF/classes に置いた場合はどうなりますか?
> > 
> > 試してみます。
> > mvnは他人のPCにあるので、明日試してみます。
> > しばしお待ち下さい。
> > 
> > 私のほうは、問題が、
> > > > public abstract AuthenticationService.authenticate(Hoge,Foo) - isBridge:false - isSynthetic:false
> > も
> > setupAspectsの中で、setInterceptorルートに流れていく事か、
> > を断定すべく
> > AopProxyに細工をして、該当のメソッドの場合に、
> > 強引にsetInterceptorにいかないようにしてみて、
> > 動かしてみようと考えています。
> > こちらも明日実行してみます。
> > ※意味無いなどあれば連絡いただけると幸いです。
> > ※なんとなく、abstractのままなので、
> >  authenticate(Hoge,Foo)が見つからないってエラーなのかと推測しています
> > 
> > 以上 引き続き宜しくお願いいたします。
> > 
> > 
> > 2013/04/02 23:30:00 Koichi Kobayashi <koichik @ improvement.jp> wrote.
> > > 小林 (koichik) です.
> > > 
> > > > TOMCAT OK_PATTERN(コンパイルはjavac 1.5.0_22 sun(oracle))
> > > 
> > > この場合、コンパイルは javac を用いて (コマンドラインで)
> > > 行っていますか? Eclipse でビルドしたものではなく?
> > > # なんとなく、Tomcat は Eclipse 上使ってるのかなと。
> > > # ちなみに Eclipse は独自のコンパイラを持っています。
> > > 
> > > 仮に、本当に javac でコンパイルしているとして、それは
> > > 
> > > > WAS7 jar ERROR_PATTERN (war/jarの作成自体はmvnでやっております。javacもsun(oracle)です)
> > > 
> > > の javac と同一バージョンですか?
> > > 
> > > mvn でビルドしているなら、target/classes 以下に
> > > コンパイルされた .class があるはずですが、それを
> > > WEB-INF/classes に置いた場合はどうなりますか?
> > > 
> > > 
> > > On Tue, 2 Apr 2013 22:37:42 +0900 (JST), suzuki_su <suzuki_su @ worksap.co.jp> wrote:
> > > 
> > > > 小林さん
> > > > 
> > > > > > 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 mailing list
> > > > Seasar-user @ ml.seasar.org
> > > > https://ml.seasar.org/mailman/listinfo/seasar-user
> > > 
> > > 
> > > -- 
> > > {
> > >   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
> > > 
> > 
> > 
> > --------------------------------------
> > 
> > WORKS APPLICATIONS
> > 
> >                鈴木 順(Sunao Suzuki)
> > 
> >  EXT    : 3079
> >  E-Mail : suzuki_su @ worksap.co.jp
> > 
> > --------------------------------------
> > _______________________________________________
> > 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


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



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