CoolDeployとHotDeployのトラブルについて知りたい(1)
Seasar2のDIコンテナを使用したWebアプリケーション開発プロジェクトに関わっているのですが、
最近、ローカル環境でうまくいく(=HotDeployで問題なし)けど、サーバに乗せて実行する(=CoolDeploy)
と問題が発生するパターンの問い合わせが増えました。
メンバーへの教育が徹底されていなかったり、習熟レベルの相違が多少なりともありますので、
そういった場面にまったく遭遇しないメンバーもいます。
メンバーのSeasar2プロダクトの教育は、もっぱら自習が主になっていて、もちろん開発規約や
サンプルなどは提供していますが、基礎部分については本をプロジェクトで購入したり、
集合研修を受講したりということを積極的には行っていないので、どうしても知識にばらつきがあります。
今は地道に資料作成をして、開発者に回覧するくらいですね。
さて、最近発生した事例では、HotDeployでは問題ないがCoolDeployだと問題発生するというパターンです。
使用しているバージョンは、2.4.41(s2-framework,s2-extension,s2-tiger)です。
WEBを調べてみると、割とよくあるパターンで、TooManyRegistrationRuntimeExceptionが発生するケースです。
public class SearchController { public DinjectionMapper dinjectionMapper = null; @Execute public String initialize(RequestModel request) { System.out.println(dinjectionMapper.hello()); return dinjectionMapper.hello(); } } public interface DinjectionMapper { public String hello(); } public class BinjectionMapperImpl implements DinjectionMapper { @Override public String hello() { return new String("hello B"); } } public class CinjectionMapperImpl implements DinjectionMapper { @Override public String hello() { return new String("hello C"); } } public class DinjectionMapperImpl implements DinjectionMapper { @Override public String hello() { return new String("hello D"); } }
上の状況では、以下のようなエラーがCoolDeploy時には発生します。
システム例外が発生しました。例外:org.seasar.framework.beans.IllegalPropertyRuntimeException [ESSR0059]クラス
(com.biz_integral.bapf.demo.application.web.employee.SearchController$$EnhancedByS2AOP$$1ea6729) のプロパティ(dinjectionMapper)の設定に失敗しました。
理由は org.seasar.framework.container.TooManyRegistrationRuntimeException: [ESSR0045]interface com.biz_integral.bapf.demo.application.web.employee.DinjectionMapper
に複数のコンポーネント (com.biz_integral.bapf.demo.application.web.employee.impl.DinjectionMapperImpl,
com.biz_integral.bapf.demo.application.web.employee.impl.BinjectionMapperImpl,
com.biz_integral.bapf.demo.application.web.employee.impl.CinjectionMapperImpl) が登録されています
seasar2のエラーログが分かりやすいので説明するまでもないのですが、1つのインターフェースに対して複数のコンポーネントが登録されているため、
どれをインジェクションしてよいか判断つかずにエラーとなっています。
CoolDeployでは、各種設定ファイルによって定義されたコンポーネントをアプリケーションサーバ起動時にS2Containerに登録しますが、
HotDeployでは必要時に必要なコンポーネントだけロードされます。
この例では、HotDeploy時には、自動バインディングのルールに従い、DinjectionMapperImplだけがロードされ、testにセットされます。
ところが、CoolDeploy時には、3つのコンポーネントがS2Containerに登録された後にgetComponent()されるので、TooManyRegistrationRuntimeExceptionが発生します。
ここからの記載はまったくの推測で、Web上を調べても明確に断言しているところが見つからなかった事項ですので、ご注意ください。
- HotDeployでは、HotDeploy対象となっているコンポーネントは、S2Containerには登録されない(と思う)
- HotDeployでは、S2Containerを使用しない訳ではなく、明示的に
タグで記載したものは登録される(と思う) - HotDeployでも、TooManyRegistrationRuntimeExceptionは発生しうる(と思う)
時間があるときに検証できたらなと思います。
ここら辺について書籍でもあったらすごくありがたいのですけど。冒頭に書いた教育の意味でも。
まあ、ソース公開されているから読めって一蹴されて終わりな気もしますし、書籍にしても売れない(一般受けしない)のですかね。。。