Archives

You are currently viewing archive for 09 July 2006

[Java] 09 July 2006 はてなブックマーク - GroovyがVelocityを引っ張るのです。その3 Twitterでつぶやく

GroovyがVelocityを引っ張るのです。その3

S2を取り込んで見ました。
現状でBindingの生成にS2を利用してます。
良くある区分値テーブルとかの情報一覧を表示する場合のコード例
Sample.gdo
  import groovy.sql.Sql
  list = new ArrayList()
  sql = new Sql(dataSource)
  sql.eachRow("select * from sys_param") { row |
    kbnData = new KbnData()
    kbnData.name_j=row.name_j
    kbnData.kbn=row.kbn
    kbnData.kbn_id=row.kbn_id
    list.add(kbnData)
  }
  if(list.size()>0){
    request.setAttribute("list",list)
  }
  class KbnData{
    @Property name_j,kbn_id,kbn
  }
Sample.htm
  <html>
  <body>
  #if($!list)
    <table>
      <tr>
        <td>kbn_id</td>
        <td>kbn</td>
        <td>name_j</td>
      </tr>
  #foreach($data in $list)
      <tr>
        <td>$data.kbn_id</td>
        <td>$data.kbn</td>
        <td>$data.name_j</td>
      </tr>
  #end
    </table>
  #else
    <h1>結果は0件</h1>
  #end
  </body>
  </html>

#S2の手軽さに感動しました。

[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の分析
«Prev || 1 || Next»