[Java] 09 July 2006 はてなブックマーク - Dispatchしたときの・・・・(原因解明編) Twitterでつぶやく

Dispatchしたときの・・・・(原因解明編)

きっとGroovy本家の人やコアな人は既に把握していて既出かもしれないのだが・・・・

ある程度原因が判明、状況から判断すると、結局スクリプト実行時にダイナミックにCategoryサポートを付加する際に、クラスの型ごとに行なっており、なおかつ実行時MetaClassImplにて関連するMetaMethodをすべて取得しているという動作に由来するようだ。

なぜこのような現象が発生するかというと、結局Servletコンテナの実装のため、もしくはGroovyの実装のためとしか言いようがない。

現象に照らし合わせて、状況を整理してみる。
1,スクリプトAでrequestのsetを実行しスクリプトBへDispatchする。
2,スクリプトBでrequestのsetを実行する。
そうするとGroovyRuntimeExceptionでAmbiguous method overloading for methodと例外が発生。

この時、最初のスクリプトAでバインドされたrequestはorg.apache.catalina.connector.RequestFacadeのインスタンスであり、GroovyCategorySupportのThreadLocalのstackにもRequestFacadeクラスのClassインスタンスをkeyとしてsetのCategoryMethodがキャッシュされる。
(詳しく言えばRequestFacadeがcategorizedClassとされ、さらにCategoryMethodにてHttpServletReqeustを対象としてキャッシュされる。)

ところが、スクリプトBでバインドされたrequestはコンテナによりDispatchされたrequestなのでorg.apache.catalina.core.ApplicationHttpRequest(HttpServletRequestWrapperのサブクラス)となっている。
そのためstackには新たにApplicationHttpRequestをkeyとしてsetのCategoryMethodがキャッシュされる。
(同じくApplicationHttpRequestがcategorizedClassとされ、さらにCategoryMethodにてHttpServletReqeustを対象としてキャッシュされる。)

このためスクリプトBの実行時にはCategoryメソッドの検索で、見事に2つのsetメソッドが存在することになり、結果的にAmbiguous method overloading for methodとなるらしい。

ということで、結局Servlet関連のrequest,session,contextに関連するCategoryサポートは利用できる局面と利用できない局面が混在することになるので、紛らわしいから利用しない方向で実装することに決定。
まあsetAttributeを書くのがそれほど苦痛とも思われないので、問題ないかと・・・

参考:
GroovyCategorySupportのコードを追ってみた。
裏マキノ式:GroovyCategorySupportの分析


Comments

チン wrote:

すみませんですが。
私も同じ状況になってしまったから
教えていただけませんか?

1,スクリプトAでrequestのsetを実行しスクリプトBへDispatchする。
2,スクリプトBでrequestのsetを実行する。


これについては詳しく説明してくださいませんか? スクリプトAとスクリプトBって 二つ画面ですか?
ありがとうございます。

26 August 2009 at 15:54

Add Comment

このアイテムは閲覧専用です。コメントの投稿、投票はできません。