[CONTAINER-350] インターセプタをS2以外で使うとエラー Created: 2009-03-15  Updated: 2009-03-17  Resolved: 2009-03-17

Status: Closed
Project: S2Container
Component/s: S2Container
Affects Version/s: 2.3.23, 2.4.34
Fix Version/s: None

Type: Bug Priority: Major
Reporter: kimura Assignee: higa
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

Class thisClass = invocation.getThis().getClass();
Class superClass = thisClass.getSuperclass();
if (superClass == Object.class)

{ return thisClass.getInterfaces()[0]; }

return superClass;

のthisClass.getInterfaces()[0]でぬるぽ。
メソッドがインターフェースのものかチェックが必要。

Class thisClass = invocation.getThis().getClass();
も、staticメソッドの場合も考慮して
method.getDeclaringClass();
の方が無難。



 Comments   
Comment by koichik [ 2009-03-17 ]

そんなわけで (どんなわけで?),クローズ.

Comment by kimura [ 2009-03-16 ]

そう説明するので、クローズでいいです。

Comment by koichik [ 2009-03-16 ]

15:38 のコメントを見ないで 16:00 のコメント書いちゃいました.きりのいい時間になるまでリロードしないで置いておいたもので.

Comment by koichik [ 2009-03-16 ]

> AOPの実装によっては、FooにtoString()を追加する可能性もあるので、微妙な話になりそうな気が・・・

だから,最初のコメントで「AOP をどのように実現しているかによって getTargetClass() の実装を差し替え可能にする必要が」あると書いたわけ.対象のクラスを求める方法は AOP の実装次第ですよね? そして AbstractInterceptor の実装は S2AOP が前提になっているわけです.

> も、イヤですか?

いやです.あまりにアドホックすぎるし意味不明.
だいたい,

public class Foo {}
public class Bar extends Foo {}

Bar の toString() メソッドに AOP を適用した場合,サブクラス化しない AOP 実装だと getTargetClass() が Foo.class を返すことになりませんか?
不都合なケース (別の AOP 実装 + static メソッド) のことだけ考えて,他のケース (S2AOP やインスタンスメソッド) が考慮されてないように見えます.

> S2Javelinを使いたかった

そちらで AbstractInterceptor がロードされるときに getTargetClass() をそちらの AOP 実装に合わせて置き換えればいいのでは?

Comment by kimura [ 2009-03-16 ]

一個前のソースは、無かったことに。。(^^;
クラス構造によって違う取れ方が出来てしまうので。

Comment by kimura [ 2009-03-16 ]

AOPの実装によっては、FooにtoString()を追加する可能性もあるので、微妙な話になりそうな気が・・・

protected Class getTargetClass(MethodInvocation invocation) {
if (invocation instanceof S2MethodInvocation)

{ return ((S2MethodInvocation) invocation).getTargetClass(); }

try{
Class thisClass = invocation.getThis().getClass();
Class superClass = thisClass.getSuperclass();
if (superClass == Object.class)

{ return thisClass.getInterfaces()[0]; }

return superClass;
}catch(RuntimeException e) {
return invocation.getMethod().getDeclaringClass();
}
}
も、イヤですか?

Comment by koichik [ 2009-03-16 ]

> return method.getDeclaringClass();
> としてもらうだけでも助かります。

できません.

public class Foo {}

の toString() メソッドにインターセプタを適用した場合,getTargetClass() は Foo.class を返すべきですが,Method#getDeclaringClass() は Object.class を返します.

Comment by kimura [ 2009-03-16 ]

S2だけだと、
protected Class getTargetClass(MethodInvocation invocation) {
if (invocation instanceof S2MethodInvocation)

{ return ((S2MethodInvocation) invocation).getTargetClass(); }

Class thisClass = invocation.getThis().getClass();
Class superClass = thisClass.getSuperclass();
if (superClass == Object.class)

{ return thisClass.getInterfaces()[0]; }

return superClass;
}
の最初のifが処理されると思うので、S2以外も考慮しているのかと思いました。
以下は、考慮されているとしての話、
例外が出て困っているので、インターフェースうんぬんはおいといて、
return method.getDeclaringClass();
としてもらうだけでも助かります。

> S2 以外でも利用したいインターセプタは,AbstractInterceptor を継承しなければいいと思います.
S2Javelinを使いたかったので、対応していただけなければ、別途方法を考えます。

Comment by koichik [ 2009-03-16 ]

このメソッドが親クラスを取得しているのは,サブクラス化によって AOP を実現する S2AOP に依存しているからであり,S2 以外での動作は想定されていません.
S2AOP 以外もサポートするということだと,AOP をどのように実現しているかによって getTargetClass() の実装を差し替え可能にする必要がありますが,それはあまりに過剰だと思います.

よって対応せずにクローズするに +1.

S2 以外でも利用したいインターセプタは,AbstractInterceptor を継承しなければいいと思います.

Comment by kimura [ 2009-03-15 ]

AbstractInterceptorで(^^;

Generated at Fri Apr 26 09:12:38 JST 2024 using Jira 9.15.0#9150000-sha1:9ead8528714127d8cfabf2446010d7e62c0a195c.