7.5.1 更新検知とリロードの概要
(1) J2EEアプリケーションのリロード方法
J2EEアプリケーションのリロードには,更新検知によるリロードと,コマンドによるリロードの2種類の方法があります。
(a) 更新検知によるリロード
更新検知によるリロードは,J2EEアプリケーション開発時のテストを支援する機能として利用できます。更新検知によるリロードを次の図に示します。
図7-6 更新検知によるリロード
![[図データ]](figure/zu055100.gif)
展開ディレクトリ形式のJ2EEアプリケーションを構成するEJBアプリケーション(EJB-JAR)やWebアプリケーション(WAR)が更新された場合に,J2EEサーバがJ2EEアプリケーションの更新を検知し,更新後のEJB-JARやWARを自動的にリロードします。
J2EEサーバは,J2EEアプリケーションの構成ファイルを定期的に監視し,構成ファイルの更新を検知すると,J2EEアプリケーションのリロードを実行します。J2EEアプリケーションの更新からリロードまでの処理の流れを次の図に示します。
図7-7 更新検知によるリロードの処理の流れ
![[図データ]](figure/zu055200.gif)
図中の1.~10.について説明します。
- J2EEアプリケーションの構成ファイルを更新します。
展開ディレクトリ形式のJ2EEアプリケーションを構成するEJB-JARやWARを更新します。
- J2EEサーバがJ2EEアプリケーションの構成ファイルの更新を検知します。
- J2EEサーバは,J2EEアプリケーションの構成ファイルを定期的に監視していて,構成ファイルが更新されると更新を検知します。J2EEアプリケーションの構成ファイルを監視して更新を検知する間隔は,更新検知インターバルとして設定します。更新検知インターバルについては,「7.5.3 J2EEアプリケーションの更新検知インターバル」を参照してください。
- 更新を検知したあと,更新するファイルをロードします。このとき,ファイルのコピー中にロードが開始されてしまい,ロードに失敗することがあります。これを回避するため,構成ファイルの更新を検知してから処理中のリクエスト数の監視を開始するまでの時間を構成ファイル更新用インターバルとして設定しておくことができます。構成ファイル更新用インターバルについては,「7.5.4 J2EEアプリケーションの構成ファイル更新用インターバル」を参照してください。
- JSPを更新した場合には,JSPの再コンパイル,またはクラスファイルの監視によって更新が検知されます。JSPのリロードについては,「7.5.6 JSPのリロード」を参照してください。
- リクエスト処理を閉塞します。
構成ファイルの更新を検知し,構成ファイル更新用インターバルで指定した時間を経過すると,J2EEアプリケーションのリロードを実行するためにリクエスト処理を閉塞します。
- EJBアプリケーション(EJB-JAR)の場合
新規リクエストが来たらエラーを返します。処理中のリクエストがある場合には,処理を続行します。ただし,Stateless Session Beanの場合は,CTMを使用することで,新規リクエストを実行待ちにできます。
- Webアプリケーション(WAR)の場合
新規リクエストが来たら実行待ちになります。処理中のリクエストがある場合には,処理を続行します。このとき,リロード遅延実行機能を使用すると,リロードの開始処理を遅らせることができます。リロード遅延実行については,「7.5.5(1) Webアプリケーションのリロード遅延実行」を参照してください。
- 参考
- 処理中のリクエストの処理が完了しない場合には,J2EEアプリケーション実行時間の監視のメソッドタイムアウトおよびメソッドキャンセルを実行することで,リロード処理を開始できます。リロードとJ2EEアプリケーション実行時間の監視との関係については,「7.5.7(2) リロードとJ2EEアプリケーション実行時間の監視との関係」を参照してください。
- J2EEアプリケーションの終了処理をします。
リロードを実行するために,J2EEアプリケーションを終了します。終了処理では,次の処理が実施されます。
- リロード前のクラスローダにローディングされたサーブレットのインスタンスが破棄されます。サーブレットがdestroyメソッドを実装している場合,destroyメソッドが実行されます。また,JSPファイルから生成されたサーブレットのインスタンスも破棄されます。このとき,JSPファイルがjspDestroyメソッドを実装していると,jspDestroyメソッドが実行されます。
- javax.servlet.ServletContextに登録されたオブジェクトは破棄されます。
- リロード前のクラスローダにローディングされたEJBのインスタンスが破棄されます。このとき,次のEJBのコールバックメソッドが実行されます。
分類 | 実行されるメソッド |
---|
Stateless Session Beanの場合 | ejbRemove PreDestroy |
Stateful Session Beanの場合 | ejbRemove PreDestroy |
Entity Beanの場合 | unsetEntityContext |
Message-driven Beanの場合 | ejbRemove |
- セッション情報をシリアライズし,セッション情報ファイルに出力します。
Webアプリケーションをリロードする場合は,リロード実行前に生成したセッション情報を,リロード後も継続して利用できます。セッション情報の引き継ぎについては,「7.5.5(2) Webアプリケーションのリロード時のセッション情報の引き継ぎ」を参照してください。
- J2EEアプリケーション単位のクラスローダを新規に作成します。
J2EEアプリケーションのリロード処理が実行されると,J2EEアプリケーション単位のクラスローダが新たに作成され,リロード後のリクエスト処理で使用されます。
- セッション情報ファイルからセッション情報を読み込み,デシリアライズします。
Webアプリケーションをリロードする場合は,セッション情報ファイルに出力されたセッション情報を新しいクラスローダに読み込みます。
- セッション情報ファイルを削除します。
- J2EEアプリケーションの開始処理をします。
- リロード後は,初回アクセス時に更新後のサーブレットのインスタンスが作成され,initメソッドが実行されます。
- 開始処理では,プールの最小値分のEJBを生成してプーリングします。このとき,次のEJBのコールバックメソッドが実行されます。
分類 | 実行されるメソッド |
---|
Stateless Session Beanの場合 | setSessionContext ejbCreate PostConstruct |
Entity Beanの場合 | setEntityContext |
Message-driven Beanの場合 | setMessageDrivenContext ejbCreate |
- リクエストの閉塞を解除し,リクエストの処理を再開します。
3.で実行待ちにしていたリクエストの処理を再開します。
(b) コマンドによるリロード
コマンドによるリロードは,J2EEアプリケーション開発時のテストを支援する機能,またはシステムの運用時にJ2EEアプリケーションの入れ替えを支援する機能として利用できます。コマンドによるリロードを次の図に示します。
図7-8 コマンドによるリロード
![[図データ]](figure/zu055300.gif)
展開ディレクトリ形式のJ2EEアプリケーションを構成するEJBアプリケーション(EJB-JAR)やWebアプリケーション(WAR)を更新した場合に,ユーザがcjreloadappコマンドを実行します。J2EEサーバは,cjreloadappコマンドを契機にJ2EEアプリケーションの更新を検知し,更新後のEJB-JARやWARを自動的にリロードします。
J2EEアプリケーションの更新からリロードまでの処理の流れを次の図に示します。
図7-9 コマンドによるリロードの処理の流れ
![[図データ]](figure/zu055400.gif)
図中の1.~4.について説明します。5.以降の手順については,更新検知によるリロードの場合と同じです。5.以降の手順については,「(a) 更新検知によるリロード」を参照してください。
- J2EEアプリケーションの構成ファイルを更新します。
展開ディレクトリ形式のJ2EEアプリケーションを構成するEJB-JARやWARを更新します。
- cjreloadappコマンドを実行します。
- cjreloadappコマンドを契機に,J2EEサーバがJ2EEアプリケーションの構成ファイルの更新を検知します。
- リクエスト処理を閉塞します。
J2EEアプリケーションのリロードを実行するためにリクエスト処理を閉塞します。
- EJBアプリケーション(EJB-JAR)の場合
新規リクエストが来たらエラーを返します。処理中のリクエストがある場合には,処理を続行します。ただし,Stateless Session Beanの場合は,CTMを使用することで,新規リクエストを実行待ちにできます。
- Webアプリケーション(WAR)の場合
新規リクエストが来たら実行待ちになります。処理中のリクエストがある場合には,処理を続行します。
- 参考
- 処理中のリクエストの処理が完了しない場合には,J2EEアプリケーション実行時間の監視のメソッドタイムアウトおよびメソッドキャンセルを実行することで,リロード処理を開始できます。リロードとJ2EEアプリケーション実行時間の監視との関係については,「7.5.7(2) リロードとJ2EEアプリケーション実行時間の監視との関係」を参照してください。
(2) リロードの適用範囲
リロードの対象として指定できるアプリケーションの種類を次の表に示します。
表7-3 リロードの対象として指定できるアプリケーションの種類
アプリケーションの種類 | 適用の有無 | 制限事項 |
---|
EJBアプリケーション(EJB-JAR) | Stateless Session Bean | △ | リロード中の新規リクエストはエラーになります。なお,CTMを利用している場合は,リロード中の新規リクエストは実行待ちになります。 |
Stateful Session Bean | △ | リロード中の新規リクエストはエラーになります。また,リロードするとアプリケーションの状態が破棄されるため,アプリケーション開始前の状態になります。 |
Entity Bean | △ | リロード中の新規リクエストはエラーになります。 |
Message-driven Bean | △ |
Webアプリケーション(WAR) | サーブレット | ○ | - |
JSP | ○ | - |
ライブラリJAR | - | ○ | - |
- (凡例)
- ○:リロードの対象として指定できる
- △:リロードの対象として指定できるが,制限事項がある
- -:該当しない
リロードの適用範囲は,次の範囲で指定できます。
- app:EJBアプリケーション(EJB-JAR)とWebアプリケーション(WAR)をリロードの対象とする。
- web:Webアプリケーション(WAR)だけをリロードの対象とする。
- jsp:JSPだけをリロードの対象とする。
注 app,web,jspは,usrconf.propertiesのejbserver.deploy.context.reload_scopeキーの指定値です。なお,noneを指定した場合は,リロード機能は無効になります。
- appを指定した場合
- EJBアプリケーションを更新すると,EJBアプリケーション,サーブレット,およびJSPがリロードされます。
- サーブレットを更新するとサーブレットとJSPがリロードされます。
- JSPを更新するとJSPがリロードされます。
- webを指定した場合
- サーブレットを更新するとサーブレットとJSPがリロードされ,JSPを更新するとJSPがリロードされます。
- サーブレットがあってJSPがない場合は,サーブレットだけがリロードされます。JSPがあってサーブレットがない場合は,JSPだけがリロードされます。
- EJBアプリケーションを更新してもリロードは動作しません。
- jspを指定した場合
- JSPを更新するとJSPがリロードされます。
- EJBアプリケーションまたはサーブレットを更新しても,リロードは動作しません。
なお,リロード機能の有効/無効は,usrconf.propertiesのejbserver.rmi.localinvocation.scopeキーで指定するローカル呼び出し最適化機能の適用範囲と,リロード機能の適用範囲の組み合わせによって決まります。ローカル呼び出し最適化機能の適用範囲とリロード機能の適用範囲の対応を次の表に示します。
表7-4 ローカル呼び出し最適化機能の適用範囲とリロード機能の適用範囲の対応
項目 | ejbserver.rmi.localinvocation.scopeキーの値 |
---|
all | app | none |
---|
ローカル呼び出し最適化の範囲 | 同一J2EEサーバ内となります。 | 同一アプリケーション内となります。 | 範囲はありません。 |
ejbserver.deploy.context.reload_scopeキーの値 | app | ×※ | ○ | ○ |
web | ○ | ○ | ○ |
jsp | ○ | ○ | ○ |
none | × | × | × |
(凡例)○:リロード機能を使用できる ×:リロード機能を使用できない
注※ 設定に誤りがあります。ejbserver.rmi.localinvocation.scope=allの場合にejbserver.deploy.context.reload_scope=appを指定すると,J2EEサーバを起動するときにメッセージが出力されて起動に失敗します。
(3) リロード時のクラスローダの構成
リロード時のクラスローダの構成は,ローカル呼び出し最適化の範囲によって異なります。ローカル呼び出し最適化の範囲とクラスローダの構成の対応を次の表に示します。なお,クラスローダの構成については,「付録H クラスローダの構成」を参照してください。
表7-5 ローカル呼び出し最適化の範囲とクラスローダの構成の対応
項目 | ejbserver.rmi.localinvocation.scopeキー※の値 |
---|
all | app | none |
---|
ローカル呼び出し最適化の範囲 | 同一J2EEサーバ内となります。 | 同一アプリケーション内となります。 | 範囲はありません。 |
クラスローダ構成 | ローカル呼び出し最適化時のクラスローダ構成になります。 | デフォルトのクラスローダ構成になります。 | デフォルトのクラスローダ構成になります。 |
注※ usrconf.propertiesに指定するキーです。
リロード機能では,ApplicationClassLoader以下,またはWebappClassLoader以下のクラスローダを入れ替えます。EJB-JARをリロードする場合,デフォルトのクラスローダ構成で,次のファイルをロードします。
- ApplicationClassLoaderでは,J2EEアプリケーションに含まれるEJB-JAR,ライブラリJAR,および参照ライブラリをロードします。
- WebappClassLoaderでは,J2EEアプリケーションに含まれるWARをロードします。
- JasperLoaderでは,J2EEアプリケーションに含まれるJSPをロードします。
EJB-JARをリロードするためにApplicationClassLoaderを入れ替える場合は,下位にあるWebappClassLoader,およびJasperLoaderも入れ替える必要があります。したがって,EJB-JAR,ライブラリJAR,参照ライブラリをリロードする場合は,WARを含めたリロードになります。
(4) エラー発生時の動作
リロード機能の使用中にエラーが発生した場合の動作を次の表に示します。
表7-6 リロード機能でのエラー発生時の動作
エラーの内容 | 結果 |
---|
リロード中(アプリケーション内で処理しているリクエストがない状態)にリクエストがサーバに来た場合 | EJB-JARの場合はクライアントにエラーが返ります。WARの場合,新規リクエストはリロードが完了するまで実行待ちとなります。 |
リロード中に例外が発生した場合(クラスファイルのロードの失敗を含む) | 更新検知は停止しないで,アプリケーションを停止します。更新を検知した場合,停止したJ2EEアプリケーションは再び開始されます。 |
リロード以外の処理(更新チェック中,構成ファイル更新用インターバル中,リロード遅延実行中)で例外が発生した場合 | 更新検知は停止しないで,J2EEアプリケーションは開始状態のまま監視を続けます。 |
J2EEアプリケーションのメソッドがハングアップなどで終了しない場合 | J2EEアプリケーション実行時間の監視でメソッドをキャンセルしないとリロードできません。また,cjreloadappコマンドを使用しないとリロードできません。 J2EEアプリケーション実行時間の監視については,「7.5.7(2) リロードとJ2EEアプリケーション実行時間の監視との関係」を参照してください。 |
(5) リロードの注意事項および制限事項
リロードに関する注意事項および制限事項を次に示します。
(a) リロード機能の使用に関する注意事項
- J2EEアプリケーションの削除について
リロードに失敗しているJ2EEアプリケーションを削除する場合は,次のどちらかの方法で削除してください。
- 更新検知によるリロード,またはcjreloadappコマンドによるリロードを再度実行してください。リロードが成功したら,J2EEアプリケーションを停止して削除してください。
- J2EEサーバを再起動したあとで,J2EEアプリケーションを削除してください。
削除後,J2EEアプリケーションを再インポートしてください。
- メモリ不足の発生について
リロード処理では,クラスローダを再作成してクラスをロードし直すため,メモリを多く消費します(消費するメモリ使用量は,J2EEアプリケーションの実装に依存します)。このため,例えば,複数のWebアプリケーションで同時にリロード処理を繰り返すとメモリ不足が発生する可能性があります。また,リロード処理によって不要となったリソースがJavaVMから解放されるタイミングは,JavaVMのガーベージコレクションの実行タイミングに依存します。リクエストのピーク時など,負荷が高いときにリロードを繰り返すと,ガーベージコレクションを実行するタイミングがなく,メモリ不足が発生する可能性が高くなります。
このため,リクエストのピーク時など負荷が高い場合には,リソースの更新は避けてください。
- メソッドキャンセルの実行について
処理中のリクエストの処理が完了しない場合には,J2EEアプリケーション実行時間の監視のメソッドタイムアウトおよびメソッドキャンセルを実行することで,リロード処理を開始できます。メソッドキャンセルを実行しても,処理をキャンセルできない場合には,J2EEサーバを再起動してください。
- 実行待ちとなっているリクエスト処理の再開について
J2EEアプリケーションのリロードでEJBアプリケーションの開始,または停止に失敗した場合,Webアプリケーションのリロード処理開始以降の新規リクエストは実行待ちとなります。実行待ちとなっているリクエスト処理を再開するためには,EJBアプリケーションを更新してリロードを実行し,リロード処理を成功させてください。Webアプリケーションを更新しても,リロードは実行されません。
- J2EEアプリケーションに含まれるRARファイルについて
アプリケーションディレクトリにRARファイルを含めている場合,RARファイルはリロード機能の対象にはなりません。RARファイルを更新した場合は,更新したRARファイルを含むJ2EEアプリケーションを,サーバ管理コマンドを使用して入れ替えてください。サーバ管理コマンドを使用してJ2EEアプリケーションを入れ替える手順については,マニュアル「Cosminexus システム運用ガイド」のJ2EEアプリケーションの入れ替えについての説明を参照してください。
(b) EJBアプリケーション(EJB-JAR)の注意事項
- リロード後にEJBを呼び出す場合には,クライアント側のソースコードでEJBHomeやビジネスインタフェースを取得し直す必要があります。リロード前に取得したインタフェース経由でEJBにアクセスした場合は例外が返ります。また,リロード実行中にEJBにアクセスした場合も例外が返ります。
- リモートインタフェースまたはリモートビジネスインタフェースを入れ替えた場合,クライアント側ではスタブを取得し直す必要があります。
- リロードを実行すると,Stateful Session Beanのクライアントとのセッションの状態は失われます。
(c) EJBアプリケーション(EJB-JAR)の制限事項
- これまでjavax.ejb.TimedObjectインタフェースを実装していなかったEJBで,javax.ejb.TimedObjectインタフェースを実装するように変更して,リロードすることはできません。リロードした場合には,次のようになります。
- 更新検知スレッドは停止させないで,J2EEアプリケーションを停止します。
- 更新を検知した場合,停止したJ2EEアプリケーションは再び開始されます。
- CMRを使用したアプリケーションはリロードできません。
(d) Webアプリケーション(WAR)の注意事項