Hot Deploy利用時に、Hot Deploy対象外クラス内でHot Deploy対象クラスを使うための正しい作法は?
「Hot Deploy」「Hot Deploy」連呼によって、今までで一番長いタイトル。。
気を取り直して本題を。
SeasarのHot Deploy機能はアプリケーションサーバーの再起動不要で修正コードがすぐに反映されるという便利な反面、ちょっとフレームワークの拡張をした時に「Hot Deployでは動くのにCool Deployでは動かない」(またはその逆)といったことにハマることが多いように思います。
S2Container本体やHot Deploy機能の理解が浅いせいもあって、自分も何回泣かされたことか。。。
今回もSAStrutsを使っていて遭遇してしまいました。
Hot Deploy対象外クラス(RequestProcessorやtaglibなど)内で、HotDeploy対象のServiceクラスやDtoクラスをgetComponentするような以下のコードを書くとClassCastExceptionが発生し、Cool Deployにすると正常に動作する、といった現象に遭遇しました。
HogeService service = SingletonS2Container.getComponent("hogeService");
service.findAll();
SeasarのHot Deploy機能がクラスローダを毎回差し替えていることから起因するものと推測し、「コンテナからオブジェクトとクラスを取得してリフレクションを使う」という以下の方法でやってみたところ、ClassCastExceptionは発生せずにうまく動作しました。
ちなみにClassUtil、MethodUtilもSeasarのリフレクション用Utilクラスです。
S2Container container = SingletonS2ContainerFactory.getContainer(); Object serviceObject = container.getComponent("hogeService"); Class serviceClass = container.getComponentDef("hogeService").getComponentClass(); Method method = ClassUtil.getMethod(serviceClass, "findAll", null); MethodUtil.invoke(method, serviceObject, null);
一応の解決は出来たのですが、すごく場当たり的な対応の気が。。
こういった問題にはSeasar的にもっと正しい作法があるように思うのですが、、、どうなんでしょうか?