Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

SingletonS2ContainerFactoryで例外が発生してコンテナが初期化できない

そんなあなたへ。S2のバージョンは2.4.40。

Cool Deploy時に、SingletonS2ContainerFactoryを使ってS2コンテナをゲットする為にこんなコードを書くと例外吐きます。

public static void main(String[]unko) {
  SingletonS2ContainerFactory.init();
  this.jdbcManager=SingletonS2Container.getComponent("jdbcManager");
}
Exception in thread "main" org.seasar.framework.container.ComponentNotFoundRuntimeException: [ESSR0046]コンポーネント(interface javax.servlet.ServletContext)が見つかりません
	at org.seasar.framework.container.impl.S2ContainerBehavior$DefaultProvider.acquireFromGetComponentDef(S2ContainerBehavior.java:165)
	at org.seasar.framework.container.impl.S2ContainerBehavior$DefaultProvider.acquireFromGetComponent(S2ContainerBehavior.java:158)
	at org.seasar.framework.container.impl.S2ContainerBehavior.acquireFromGetComponent(S2ContainerBehavior.java:62)
	at org.seasar.framework.container.impl.S2ContainerImpl.getComponent(S2ContainerImpl.java:124)
	at org.seasar.framework.container.SingletonS2Container.getComponent(SingletonS2Container.java:43)
(以下略)

SingletonS2ContainerFactoryはサーブレット起動時にインスタンスを1個だけ作ってそいつをServletContext経由でみんなで使いまわすらしく、アプリケーションから使うことは出来ないようです。かといってサーブレット作ってそこを叩いてインスタンス取得してロジック実行とか、mainメソッドでcron経由で集計バッチ作るだけなのにdnbkじゃないですか。

で、コンテナを取得するにはS2ContainerFactoryが利用可能と公式ドキュメントに書いてあった。

ただ、僕の場合はSAStrutsを使っているため、app.diconだけを読み込むだけでは他のコンポーネントが初期化されなかった。どうもcreateメソッドは委譲関係を読みとって再帰的によしなにやってくれるわけじゃないらしい。

で、APIドキュメントを見たらそれっぽいのがあった。以下サンプル。これでめでたくS2コンテナがアプリケーションから初期化できた。

  S2ContainerFactory.configure("app.dicon");
  S2Container container = S2ContainerFactory.getConfigurationContainer();
  JdbcManager jdbcManager=(JdbcManager) container.getComponent("jdbcManager");

キャストしてるのださいけど、まぁいいや・・・・。JDBCManagerラブ。S2非依存になれば狂喜乱舞するJavaデベロッパーいっぱいいそうw