instance="session"でエラー発生
instance="session" or "request"にすると、以下のエラーが発生する。
[ERROR] 2005-10-02 19:23:03 StandardContext#loadOnStartup() サーブレット /hoge がload()例外を投げました org.seasar.framework.exception.EmptyRuntimeException: [ESSR0007]sessionはnullあるいは空であってはいけません at org.seasar.framework.container.deployer.SessionComponentDeployer.deploy(SessionComponentDeployer.java:28) at org.seasar.framework.container.impl.ComponentDefImpl.getComponent(ComponentDefImpl.java:75) at org.seasar.framework.container.impl.S2ContainerImpl.getComponent(S2ContainerImpl.java:89) at org.seasar.framework.container.assembler.AutoPropertyAssembler.assemble(AutoPropertyAssembler.java:44) at org.seasar.framework.container.deployer.SingletonComponentDeployer.assemble(SingletonComponentDeployer.java:47) at org.seasar.framework.container.deployer.SingletonComponentDeployer.deploy(SingletonComponentDeployer.java:27) at org.seasar.framework.container.deployer.SingletonComponentDeployer.init(SingletonComponentDeployer.java:55) at org.seasar.framework.container.impl.ComponentDefImpl.init(ComponentDefImpl.java:249) at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:344) at org.seasar.framework.container.factory.SingletonS2ContainerFactory.init(SingletonS2ContainerFactory.java:36) at org.seasar.framework.container.servlet.S2ContainerServlet.init(S2ContainerServlet.java:47) at javax.servlet.GenericServlet.init(GenericServlet.java:211) 〜(省略)〜
当然、web.xmlで
<filter> <filter-name>s2filter</filter-name> <filter-class>org.seasar.framework.container.filter.S2ContainerFilter</filter-class> </filter> <filter-mapping> <filter-name>s2filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>s2servlet</servlet-name> <servlet-class>org.seasar.framework.container.servlet.S2ContainerServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
という設定はしてますよ、はい。その辺りは抜かりなく。
実際、別のフィルタでS2Containerのrequest,response,sessionとういコンポーネント名でgetしてみると、ちゃんとオブジェクトは入ってるんです。
つーか、Tomcat起動時に上記のエラーが発生するんですよ。これが。
で、色々試した結果、大体見えてきた。
HogeLogicImplクラスの中で、UserImpl(インタフェースUser)をDIしたい場合に、
<components> <component name="user" class="hoge.entity.impl.UserImpl" instance="session" /> <component class="hoge.logic.impl.HogeLogicImpl" instance="request" ></component> </components>
という設定をすると、起動時にエラーは発生せず、実行も可能。
<components> <component name="user" class="hoge.entity.impl.UserImpl" instance="session" /> <component class="hoge.logic.impl.HogeLogicImpl" instance="singleton" ></component> </components>
のようにDI先コンポーネントがsingletonだと、起動時にエラー発生!
エラーメッセージから解析するのはとっても難しいけど、原因がわかった今となっては、そりゃそうだ、という感じかも。
つまり、
- ライフサイクルがsingletonなコンポーネントHogeLogicImplは、起動時にインスタンス化されてコンテナに設定される。
- その時点で、HogeLogicImplが必要なコンポーネントがDIされる。
- その時点では、sessionなどないのでUserImplは取得できない。
- エラー!!
というわけだ。
ま、そりゃそうだ。
でも、エラーメッセージがわかりづらいっす。検索してもぜんぜん情報ヒットしないし。
実際、マニュアルにも明示的には書いてないですよね。ふつーに気付けよッてことかしら?これにハマったのって僕だけ?
こういう設定上の制約は、機械的にチェックできるんで、kijimunaで警告してくれるようになると大変助かります。
…と、世界の隅っこでぼそっとつぶやいておこう。