World Map
Java Service Wrapperは、御社Javaアプリケーション製品の安定した信頼性を高める最短最善の方法です。
  • Free Trial
  • Buy Now
TestWrapperサンプル・アプリケーション

TestWrapperサンプル・アプリケーションを動かす

このセクションでは、Wrapperに同梱して提供しているTestWrapperサンプル・アプリケーションを活用して、 いくつかのWrapperの障害リカバリー(回復)機能の紹介をします。

コンソール内で動かす

一旦、Wrapperのバイナリ版をインストールしたり、あるいは、ソース版でビルドを実行したりすれば、 すぐにサンプル・アプリケーションを実行できる状態にあります。

TestWrapperサンプル・アプリケーションは、 Java Service Wrapperのリカバリー(回復)機能のテストとしても利用できます。

サンプル・アプリケーションを実行するには、ご利用中のアプリケーションの bin」ディレクトリーへ移動して、次のスクリプトを実行してください:

Windows:
TestWrapper.bat
Linux / Solaris:
./TestWrapper start

注意

Solaris TestWrapper スクリプトでは、 「/var/run」ディレクトリーに、 PIDファイルの書き込みを試みます。 もし、ルート・ユーザーとしてログインしていない場合、失敗するでしょう。 これを改善するためには、単純にスクリプト内の PIDDIR変数を書き換えるか、 あるいは、ルート・ユーザーとしてログインしてください。 もしルート・ユーザーとしてログインする際には、 X サーバーを利用できるように適切なパーミッション(アクセス権限)があることを確認してください。 さもなければ、TestWrapper GUI を見ることができません。

Windowsコンソールは、[CTRL]+[C]のキー操作でキレイに停止することができますが、 Linux や Solarisバージョンでは、 stop]パラメータでスクリプトの実行が必要です:

Linux / Solaris:
./TestWrapper stop

Linux や Solarisバージョンは、アプリケーションを再起動する機能も提供しています:

Linux / Solaris:
./TestWrapper restart

TestWrapperサンプル・アプリケーションが起動すると、次のダイアログが表示されます:

また、コンソール内で次のようにも見えるはずです:

コンソール出力例:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()

コンソール出力の解説から始めます。 最初の列のデーターでは、ソース出力が表示されます。 「wrapper」で始まる行は、 ネイティブ・Wrapper アプリケーションからの出力です。 「jvm 1」で始まる行は、JVMからの出力です。 「jvm」に続く数字は、Wrapperが起動を繰り返したJVM番号を示します。 TestWrapperサンプル・アプリケーションのダイアログを再生を開始をすると、どのように動作しているのか見ることができます。

コンソール出力は、全てログ化され、 「logs/wrapper.log」 に出力されます。 そのログ出力形式は、 コンソール出力形式とは異なり、自由にカスタマイズすることができます。

ログファイルの出力例:
wrapper  | 2001/12/06 16:18:27 | --> Wrapperがコンソールとして開始しました
wrapper  | 2001/12/06 16:18:28 | JVM起動中...
jvm 1    | 2001/12/06 16:18:29 | 初期化中...
jvm 1    | 2001/12/06 16:18:30 | Wrapper (Version 3.x.x)
jvm 1    | 2001/12/06 16:18:30 | 
jvm 1    | 2001/12/06 16:18:30 | start()

ご覧のとおり、TestWrapperサンプル・アプリケーションには多くのボタンが用意されています。 それらは、Wrapperの様々な機能をテストするのにご利用いただけます。 各ボタンが実行されると、コンソール内の出力でご覧のとおりで、下記の説明のように表示されます。

Wrapper機能をテストする (内部終了と問題)

このセクションでは、様々なイベントに対して、Wrapperがどのように応答するのかをご紹介します。 TestWrapperサンプル・アプリケーションに用意された様々なボタンを押すことで、 自宅で安全に、各種イベントのテストすることができます。

Stop

この[Stop]ボタンは、 [WrapperManager.stop(0)] をコールすることで、キレイにJVMを終了します。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | stop(0)
wrapper  | <-- Wrapperが停止しました

ご覧のとおり、アプリケーションは、 [stop()]メソッドを呼び出し、キレイに停止しました。

Exit

この[Exit]ボタンは、「System.exit()」への予想外のコールをトラップして キレイにアプリケーションを停止するWrapperの能力をテストします。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | stop(0)
jvm 1    | here
wrapper  | <-- Wrapperが停止しました

練習として、 conf/wrapper.confファイルを編集して(コメント記号を外して)、 [wrapper.disable_shutdown_hook=TRUE] プロパティを有効化してください。 (この練習を終えたら忘れずに元に戻してください)

では、TestWrapperサンプル・アプリケーションを再始動してみましょう。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | JVM が予想外に終了しました。
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

お気づきかと思いますが、もはや「System.exit()」へのコールを Wrapperは検知しないため、JVMは単にクラッシュして再起動します。

注意

シャットダウン・フックは、Javaバージョン1.2ではサポートしておらず、 「System.exit」へのコールは、 結果として、常にJVMが再起動することになります。 Javaバージョン1.2を使って、JVMをシャットダウンするためには、 [WrapperManager.stop(exitCode)] をコールする必要があります。

注意

Wrapperバージョン3.4.x以上では、Javaバージョン1.4.x以上をサポートしています。 サポートされているJVM(Javaバーチャルマシン)をご覧ください。

Halt

この[Halt]ボタンは、JVMを強制的に停止するために、とても低いレベルのメソッドをコールします。 このケースでは、シャットダウン・フックが実行されておらず、 Wrapperはそれを検知する手段がありません。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | JVM が予想外に終了しました。
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

Wrapperは「JVMがクラッシュした」と想定して、JVMを再起動させていることに注目してください。

再起動リクエスト

WrapperManager.restart()] をコールすることで、JVMをキレイに再起動しています。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | JVMが再起動をリクエストしました。
jvm 1    | stop(0)
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

ご覧のとおり、アプリケーションは、 [stop()]メソッドを呼び出し、キレイに再起動しました。

アクセス違反

Sun JVM バージョン1.3 のバグを利用して、JVMでアクセス違反を起こしてみます。 (IBM JVMでは動きません。あるいは、もしかしたら動作すると言えるかもしれませんが...)

コンソール出力 (SUN JVM):
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | 警告: アクセス違反の引き起しを試行中...
jvm 1    | #
jvm 1    | # HotSpot Virtual Machine Error, EXCEPTION_ACCESS_VIOLATION
jvm 1    | # Please report this error at
jvm 1    | # http://java.sun.com/cgi-bin/bugreport.cgi
jvm 1    | #
jvm 1    | # Error ID: 4F533F57494E13120E43505002D4
jvm 1    | #
jvm 1    |
jvm 1    | abnormal program termination
wrapper  | JVM が予想外に終了しました。
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

ご覧のとおり、JVMにアクセス違反を引き起こし、エラーダンプを表示して、終了しています。 Wrapperは、これを即座に検知して、5秒間のポーズ後、 新しいJVMでアプリケーションを再起動したため、その接頭が「jvm 2」になっています。 クラッシュに関しての有効な情報は、詳しく参照できるように全てログ化されています。

ネイティブ・アクセス違反

Wrapperは、軽量なネイティブ・ライブラリーを含んでおり、 システム・イベントを取り扱うときに利用されます。 ライブラリーには、ネイティブ・メソッドも含んでおり、テスト用に利用され、 「NULL」参照によるネイティブ・コードでアクセス違反を引き起こします。

JVM次第ですが、これは異なる出力結果となります。 この下記の例では、保存に1分かかりますが、コア・ダンプを作成します。 その所要時間にもよりますが、 JVMがハングアップしているように見える可能性もあり、 その場合、Wrapperがハングアップと検知して強制終了して再起動させる可能性もあります。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | 警告: アクセス違反の引き起しを試行中...
jvm 1    | #
jvm 1    | # An EXCEPTION_ACCESS_VIOLATION exception has been detected in native code outside the VM.
jvm 1    | # Program counter=0x8f7105f
jvm 1    | #
wrapper  | JVM is hung: JVMからのシグナル待ちのタイムアウト。
wrapper  | JVM はリクエストに応じて終了しませんでした、中止しました
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

JVMハングアップのシミュレーション

このテストでは、Wrapperに「JVMがハングアップした」と思わせるテストです。 30秒後にタイムアウトで、WrapperはJVMがリカバリー(回復)しないと判断して、JVMを再起動させます。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | 警告: JVMがハングアップしているように見えます...
wrapper  | JVMハングアップの模様: JVMからのシグナル待ちのタイムアウト。
wrapper  | JVM はリクエストに応じて終了しませんでした、中止しました
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

Wrapper機能のテスト (外部終了)

上記のセクションでは、アプリケーションを終了したり、自らの意思で終了させるなど、全ての例をカバーしました。 その他にも、外部要因からWrapper自身を守ることができる機能について紹介します。

[CTRL]+[C]

ほとんどのJavaアプリケーションでは、ユーザーの[CTRL]+[C]のキー操作で、 むしろ強制的に落ち、Windowsからログアウトします。 シャットダウン・フックを使うことで、これらの問題を回避することができますが、 Wrapperはネイティブ・ライブラリーを使い、 直接的にシステム・シグナルを検知する機能を実装しています。 これにより、Windowsサービルの1としてインストールされたJavaアプリケーションが ユーザーのログオフ時に停止されることなく、継続して動作できることを可能にしています。

テストとして、コンソール・ウィンドウ内で、[CTRL]+[C]のキー操作を試してください。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | [CTRL]+[C]キー操作がトラップされました。  シャットダウン中。
jvm 1    | stop(0)
wrapper  | <-- Wrapperが停止しました

コンソール・アプリケーションがまだ動作しているときに、 ログアウトすることにより、バリエーションを見ることができます。 Wrapperは、正しくアプリケーションを終了します。

コンソール出力:
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    | 
jvm 1    | start()
wrapper  | ユーザーがログアウトしました。シャットダウン中。
jvm 1    | stop(0)
wrapper  | <-- Wrapperが停止しました

Linux や Solaris プラットフォーム上では、 Wrapperの起動に利用したスクリプトをコンソール・コマンドに引き渡している場合に、 [CTRL]+[C]のキー操作を利用することができます。

start]コマンドを使ってWrapperが起動した場合には、 サービス/デーモンとして異なるプロセスで開始するため、コンソールにアクセスできません。 Wrapperの生成されたインスタンスを停止するためには、 Wrapperの起動に利用したのと同じスクリプトを実行してください。 今回だけ[stop]コマンドを指定します:

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | シャットダウン中。
jvm 1    | stop(0)
wrapper  | <-- Wrapperが停止しました

終了プロセス

無理そうですが、 アプリケーション・プロセスが他の外部アプリケーションによって強制終了されることも可能です。 このテストは、突然、JVMが自発的に停止するケースをシミュレートします。 UNIXシステム上では、 「kill -9」シグナルで、Javaプロセスを強制終了することができます。 Windowsプラットフォーム上では、タスク・マネージャーを開き、プロセス・タブを選択し、 [java.exe]プロセスを探して、それを強制終了してください。

コンソール出力:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
wrapper  | JVM が予想外に終了しました。
wrapper  | JVM起動中...
jvm 2    | 初期化中...
jvm 2    | Wrapper (Version 3.x.x)
jvm 2    |
jvm 2    | start()

Wrapperは何も問題なく再起動されるでしょう。

もし、Javaプロセスを強制終了ではなく、Wrapperプロセスが強制終了されるならば、 現時点でリカバリー(回復)・モードが動いています。 Javaプロセス内部のWrapperManagerが、Javaプロセスが放棄されたと想定して、Wrapperの消失に反応しています。 これにより、Wrapperプロセスが落ちた後、30秒でキレイにJVMがシャットダウンされます。

システムの高い負荷 や システム・サスペンド

WrapperやJVM、あるいは両方が、ある長い時間、CPUサイクルを与えられず拒否されるケースがあります。 これが起きるのは、 非友好的にリソース・プロセスが、ある一定の期間、CPUの100%消費を始めている場合に、 起きることがあります。 また、ユーザーがシステムをRAMやディスクにサスペンドした場合にも、発生する可能性があります。 システムがレジューム(再開)されるとき、全ての実行中のアプリケーションに消失時間が発生します。 Wrapperは、この「消失時間の発生」を認識する機能を備えており、 JVMプロセスの不要な再起動を回避することが可能になります。 次の出力では、レジューム(再開)される前の255秒間、 RAM(メモリ)へサスペンドされるときに何が起きるかを、示しています。

コンソール出力例:
wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | JVM起動中...
jvm 1    | 初期化中...
jvm 1    | Wrapper (Version 3.x.x)
jvm 1    |
jvm 1    | start()
jvm 1    | JVMプロセスは、255秒間、CPU時間を何も受信していません。タイムアウトを延長中。
wrapper  | Wrapperプロセスは、255秒間、CPU時間を何も受信していません。タイムアウトを延長中。

Windowsサービスの1つとして動かす

Windowsサービスの1つとして動かすとき、TestWrapperサンプル・アプリケーションはダイアログを表示することができません。 そのため、このサンプル・アプリケーションは、あまり面白くありませんが、 しかしながら、私達が、2、3のテストをして、 Windowsサービスの1つとして正しくWrapperが動作することを実証しました。

最初にすることは、TestWrapperサンプル・アプリケーションのインストールです。 次のコマンドを実行して、Windowsサービスの1つとして動かしてください:

InstallTestWrapper-NT.bat
この出力が見えます:
wrapper  | TestWrapperサンプル・アプリケーション インストールされました。

一旦、TestWrapperサンプル・アプリケーションがサービスの1つとしてインストールしたら、 早速、それをスタートしてみましょう。

コマンド:
net start TestWrapper
この出力が見えます:
TestWrapperサンプル・アプリケーション サービスを取り外しました。
TestWrapperサンプル・アプリケーション service was started successfully.

そのサービスは、次のコマンドを実行して、アンインストールすることができます:

コマンド:
UninstallTestWrapper-NT.bat
もしサービスが実行中ならば、この出力が見えます:
wrapper  | サービスは動作しています。停止中...
wrapper  | 停止の待機中...
wrapper  | TestWrapperサンプル・アプリケーションが停止しました.
wrapper  | TestWrapperサンプル・アプリケーション removed.

logs/wrapper.log」 の中身を見ると、このコンソールにとても類似した出力が見られると思います。 今回を除き、そのスタート・メッセージは、アプリケーションがサービスとして開始されたことを知らせています。

wrapper.log
wrapper  | 2001/12/06 17:34:21 | --> Wrapperがサービスとして開始しました
wrapper  | 2001/12/06 17:34:21 | JVM起動中...
jvm 1    | 2001/12/06 17:34:22 | 初期化中...
jvm 1    | 2001/12/06 17:34:22 | Wrapper (Version 3.x.x)
jvm 1    | 2001/12/06 17:34:22 |
jvm 1    | 2001/12/06 17:34:22 | start()

Windowsサービス上で起きる、いくつかその他のアクションの結果です:

ユーザー・ログアウト と その復帰

ユーザーのログアウトでログ・エントリが作成されますが、サービスには影響ありません。

wrapper.log
wrapper  | 2001/12/06 17:39:39 | --> Wrapperがサービスとして開始しました
wrapper  | 2001/12/06 17:39:40 | JVM起動中...
jvm 1    | 2001/12/06 17:39:40 | 初期化中...
jvm 1    | 2001/12/06 17:39:40 | Wrapper (Version 3.x.x)
jvm 1    | 2001/12/06 17:39:40 |
jvm 1    | 2001/12/06 17:39:41 | start()
wrapper  | 2001/12/06 17:40:07 | ユーザーがログアウトしました。無視しました。
jvm 1    | 2001/12/06 17:40:07 | ControlEvent(202)

マシン再起動

これは、「シャットダウン」シグナルに続く、「ログアウト」シグナルの結果になります。 サービスがキレイにシャットダウンされると、マシン再起動の後、戻ってきます。

ユーザーのログアウトでログ・エントリが作成されますが、サービスには影響ありません。

wrapper.log
wrapper  | 2001/12/06 17:41:04 | --> Wrapperがサービスとして開始しました
wrapper  | 2001/12/06 17:41:05 | JVM起動中...
jvm 1    | 2001/12/06 17:41:05 | 初期化中...
jvm 1    | 2001/12/06 17:41:05 | Wrapper (Version 3.x.x)
jvm 1    | 2001/12/06 17:41:05 |
jvm 1    | 2001/12/06 17:41:05 | start()
wrapper  | 2001/12/06 17:41:25 | ユーザーがログアウトしました。無視しました。
jvm 1    | 2001/12/06 17:41:26 | ControlEvent(202)
wrapper  | 2001/12/06 17:41:27 | マシンがシャットダウンしています。
jvm 1    | 2001/12/06 17:41:27 | ControlEvent(203)
jvm 1    | 2001/12/06 17:41:28 | stop(0)
wrapper  | 2001/12/06 17:41:29 | <-- Wrapperが停止しました
wrapper  | 2001/12/06 17:44:12 | --> Wrapperがサービスとして開始しました
wrapper  | 2001/12/06 17:44:12 | JVM起動中...
jvm 1    | 2001/12/06 17:44:17 | 初期化中...
jvm 1    | 2001/12/06 17:44:21 | Wrapper (Version 3.x.x)
jvm 1    | 2001/12/06 17:44:21 |
jvm 1    | 2001/12/06 17:44:23 | start()

Linux/Solarisサービスの1つとして動かす

UNIX 環境において『サービスの1つとして』対 『コンソール・アプリケーションとして』の動作中には、 何も異なる点はありません。