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"/>

動き出した。動き出した。
いろいろ試してみよー