HOT deploy時のActionからのforward
forwardしたときにthreadが変わってしまって(getName()はいっしょだけど、ClassLoaderは変わってた。。。スレッドIDとかみれないのかな、、、)うまく動かなかったんだけど、例外のログをみると下のような部分が出力されてた。
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:704) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:474) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:409) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
これってあれだよね。forwardした後、Filterを設定できるってことだよね。。。
ちょっと調べてみたら、Servlet2.4ではFilterに対していろいろ適用する位置を指定できるみたい。これはよいことだ。早速、web.xmlを
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> : : <filter> <filter-name>hotdeployfilter</filter-name> <!-- <filter-class>org.seasar.framework.container.hotdeploy.HotdeployFilter</filter-class> --> <filter-class>org.seasar.struts.examples.MyHotDeployFilter</filter-class> </filter> : : <filter-mapping> <filter-name>hotdeployfilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> : : </web-app>
こんな感じにしてとりあえずのFilterを
public class MyHotDeployFilter implements Filter { private static final String KEY = "org.seasar.struts.examples.MyHotDeployFilter_CLASSLOADER"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request.getAttribute(KEY) == null) { OndemandBehavior ondemand = (OndemandBehavior) S2ContainerBehavior .getProvider(); ondemand.start(); request.setAttribute(KEY, Thread.currentThread().getContextClassLoader()); try { chain.doFilter(request, response); } finally { ondemand.stop(); } } else { ClassLoader cl = (ClassLoader) request.getAttribute(KEY); Thread.currentThread().setContextClassLoader(cl); chain.doFilter(request, response); } } public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } public void destroy() { // TODO Auto-generated method stub } }
として動かしてみると、、、
うっっっっなんかエラーがでてる。。。。
WARN 2006-07-10 22:30:08,171 [main] SchemaLocation: schemaLocation value = 'http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd' must have even number of URI's. org.xml.sax.SAXParseException: SchemaLocation: schemaLocation value = 'http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd' must have even number of URI's. at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) at org.apache.xerces.util.ErrorHandlerWrapper.warning(Unknown Source)
でも一応Tomcatは起動したみたいだし、、、
確認すると、、、動いた!!
うーむ、S2StrutsのHOT deployはTomcat5系のみで動作しますっということで。(違った。Servlet2.4対応のコンテナで動作して、Tomcat5.0.28で動作確認しましたかな。)
動かしていたら、ClassCastExceptionが発生したけど、これはOK。S2Daoのキャッシュが問題のやつ。最新のをとってくればいいんだけど、そうするとS2本体も最新にしないといけなくて、そうするとまた他の問題で動かなくなるかもしれないので、とりあえず、独自のDaoMetaDataFactoryを作成(S2Dao1.0.34だったので、ついでに1.0.35にバージョンアップ)
public class MyDaoMetaDataFactoryImpl extends DaoMetaDataFactoryImpl { public MyDaoMetaDataFactoryImpl(DataSource arg0, StatementFactory arg1, ResultSetFactory arg2, AnnotationReaderFactory arg3) { super(arg0, arg1, arg2, arg3); } public synchronized DaoMetaData getDaoMetaData(Class daoClass) { DaoMetaData dmdi = createDaoMetaData(daoClass); return dmdi; } }
そしてdao.diconを少し手を加えて
<!-- <component class="org.seasar.dao.impl.DaoMetaDataFactoryImpl"/> --> <component class="org.seasar.struts.examples.MyDaoMetaDataFactoryImpl"/>
動き出した。動き出した。
いろいろ試してみよー