2011年12月6日火曜日

GlassFish3.1.1 + SAStrutsの動かし方

GlassFish上でSAStrutsを動かすと、以下のようなエラーが発生することがあります。
java.lang.NullPointerException
at org.apache.jasper.compiler.TagLibraryInfoImpl.toString(TagLibraryInfoImpl.java:129)
at java.lang.String.valueOf(String.java:2826)
at java.lang.StringBuilder.append(StringBuilder.java:115)
at java.util.AbstractMap.toString(AbstractMap.java:490)
at java.lang.String.valueOf(String.java:2826)
at java.lang.StringBuffer.append(StringBuffer.java:219)
at org.seasar.extension.filter.util.RequestDumpUtil.dumpContextAttributes(RequestDumpUtil.java:86)
at org.seasar.extension.filter.RequestDumpFilter.dumpAfter(RequestDumpFilter.java:191)
at org.seasar.extension.filter.RequestDumpFilter.doFilter(RequestDumpFilter.java:129)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.seasar.framework.container.hotdeploy.HotdeployFilter.doHotdeployFilter(HotdeployFilter.java:86)
at org.seasar.framework.container.hotdeploy.HotdeployFilter.doFilter(HotdeployFilter.java:67)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:785)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:649)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:483)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:454)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:350)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:300)
at org.seasar.struts.filter.RoutingFilter.forward(RoutingFilter.java:219)
at org.seasar.struts.filter.RoutingFilter.doFilter(RoutingFilter.java:152)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.seasar.framework.container.hotdeploy.HotdeployFilter.doHotdeployFilter(HotdeployFilter.java:99)
at org.seasar.framework.container.hotdeploy.HotdeployFilter.doFilter(HotdeployFilter.java:67)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.seasar.extension.filter.EncodingFilter.doFilter(EncodingFilter.java:69)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:680)
原因を調べてった所、問題が2点あって、
①requestDumpFilterが動いてない。
②jar中のtld(タグライブラリの記述)を読み込めていない。

で、なおし方。
以下の2つをやるとうごきます。
requestDumpFilterが動かないようなので、Webアプリの/WEB-INF/web.xmlの以下の場所をコメントアウトします。


<!-- requestDumpFilter が動かないので、コメントアウト
<filter-mapping>
<filter-name>requestDumpFilter</filter-name>
<url-pattern>*.do</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
-->

②jarの中のtldが読み取れないので、外に出します。
tldsa-struts-X.X.X-XXX.jar(Xはバージョン番号。多分皆さんのWebアプリのWEB-INF/libの中に入ってます。)をZIP解凍ツールで解凍して、中の/META-INF/s.tldと、/META-INF/f.tldを取り出します。で、WebアプリのWEB-INF直下においてください。同じく、struts-1.2.9.jarの中から/META-INF/struts-html.tld、/META-INF/struts-bean.tld、/META-INF/struts-tiles.tldを取り出して、WEB-INF直下においてください。
で、web.xmlのjsp-configタグの中に、以下を入れます。

<jsp-config>

<!-- ここから-->
<taglib>
<taglib-uri>http://struts.apache.org/tags-beantaglib-uri>
<taglib-location>/WEB-INF/struts-bean.tldtaglib-location>
<taglib>

<taglib>
<taglib-uri>http://struts.apache.org/tags-htmltaglib-uri>
<taglib-location>/WEB-INF/struts-html.tldtaglib-location>
<taglib>

<taglib>
<taglib-uri>http://jakarta.apache.org/struts/tags-tilestaglib-uri>
<taglib-location>/WEB-INF/struts-tiles.tldtaglib-location>
<taglib>

<taglib>
<taglib-uri>http://sastruts.seasar.orgtaglib-uri>
<taglib-location>/WEB-INF/s.tldtaglib-location>
<taglib>

<taglib>
<taglib-uri>http://sastruts.seasar.org/functionstaglib-uri>
<taglib-location>/WEB-INF/f.tldtaglib-location>
<taglib>
<!-- ここまで -->

<jsp-property-group>

これで動くようになります。
Glassfish3.1は、アプリケーションバージョニングがとても便利で、Webアプリケーションの無停止バージョンアップが可能になっています。
ぜひお試しあれ。