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

問題

Java アプリケーションを UNIX デーモンとして動かすには?

Arrow

解決!

Java Service Wrapper を使用することで、ごくわずかなステップで Java アプリケーションをデーモンプロセスとして簡単にインストールし、実行することができます。

通常、Java アプリケーションは UNIX システム上のターミナルで実行されます。これを行うには、常にユーザーアカウントをシステムにログオンさせ、ターミナルを開く必要があります。

これは、セキュリティからシステムパフォーマンスまで、ユーザーがターミナルで間違ったキーを押して Java アプリケーションを強制終了するリスクがあるなど、いくつかの欠点があります。

Java Service Wrapper は、Java アプリケーションをデーモンとしてインストールできるようにすることで、これらの問題に対処します。 OS 上で利用可能なサービス管理ツール(init システムとも呼ばれます)の自動検出を提供したり、アプリケーションをデーモンとして起動する際に特定のシステムを使用するように設定したりすることができます。

Windows をご利用ですか?「Windows サービスとして実行手順」ページをご覧ください。

デーモンとは?

UNIX デーモンは、 Windows サービスと同様、アプリケーションをバックグラウンドで実行させ、システム起動時に自動的に起動されます。

問題は Java は単独でデーモンとして実行できません。ユーザーはマシーンをログオフさせるだけで Java がシャットダウンされます。

Java Service Wrapper はそれを可能にするだけでなく、Java アプリケーションをデーモンとして簡単に実行させます。 また、高度なフェールオーバーエラー回復および分析機能を追加して、アプリケーションに最大限の稼働時間を確保します。

シンプルな HelloWorldServer Java クラス

この例では、バックグラウンドで実行される HelloWorldServer アプリケーションを利用します。 この例のような HelloWorldServer アプリケーションを作成して構築する方法については、アプリケーションの概要詳細をご覧ください。

HelloWorldServer クラスを包む(ラップする)

HelloWorldServer クラスをデーモンへ移管するには、まず初めのステップとして、 弊社のサンプルアプリケーションが動くように Java Service Wrapper を設定します。 大多数の Java アプリケーションに対して言えることですが、Java コードを書く必要なく、間単に設定が可能です。

ディレクトリ構成

Wrapper は非常に柔軟性に富んでおり、いかなるディレクトリー構造においても動作するように設定することができます。 この例のように、やや複雑なアプリケーションにおいても、 再利用できるようなシンプルなディレクトリー構造にすることをおススメします。 自分で選択した任意のディレクトリー下に、次のディレクトリー構造を再形成してください。 これをルートディレクトリーを「$(EXAMPLE_HOME) と呼びます。 これは、HelloWorldServer 概要で説明しているディレクトリー構造の拡大版です。

ディレクトリ構成:
$(EXAMPLE_HOME)/
$(EXAMPLE_HOME)/bin/
$(EXAMPLE_HOME)/conf/
$(EXAMPLE_HOME)/lang/
$(EXAMPLE_HOME)/lib/
$(EXAMPLE_HOME)/lib/classes/
$(EXAMPLE_HOME)/logs/

Java Service Wrapper を入手する

ダウンロードページから、 ご自分の利用しているOSに対応する Java Service Wrapper の最新版をダウンロードし、ダウンロードした圧縮ファイルを任意のディレクトリーに解凍してください。ここでは、解凍先ディレクトリーを $(WRAPPER_HOME)と呼びます。

Wrapper ファイルをコピーする

Java Service Wrapper は UNIX 上で4つの主要なコンポーネントで成り立っています: Wrapper バイナリjar ファイル、jarファイルで使われるネイティブライブラリー、および Wrapper を起動し、デーモンとして制御するなどのアクションを実行するために使用されるシェルスクリプトです。 以下のように、そのファイルをコピーしてください:

ファイルをコピーする:
cp $(WRAPPER_HOME)/bin/wrapper $(EXAMPLE_HOME)/bin/wrapper
cp $(WRAPPER_HOME)/lib/wrapper.jar $(EXAMPLE_HOME)/lib/wrapper.jar
cp $(WRAPPER_HOME)/lib/libwrapper.so $(EXAMPLE_HOME)/lib/libwrapper.so
cp $(WRAPPER_HOME)/src/bin/sh.script.in $(EXAMPLE_HOME)/bin/helloworldserver

その後、スクリプトファイルを実行可能にする必要があります:

chmod +x helloworldserver

ライセンスキー:

Java Service Wrapper のスタンダード版やプロフェッショナル版を動作させるためにライセンスキーが必要です。 Wrapper には、トライアルライセンス(15分間)のライセンスキーを同梱しています。 今、それもコピーしてください。 ページ上部にある「FREE TRIAL」ボタンをクリックして、長期間トライアルライセンスの申請をすることもできます。

ライセンスキーファイルをコピー:
cp $(WRAPPER_HOME)/src/conf/wrapper-license-time.conf $(EXAMPLE_HOME)/conf/wrapper-license.conf

Wrapper コンフィギュレーションファイル:

最後に、デフォルトの Wrapper コンフィギュレーションファイルをコピーします。 その設定ファイルの編集方法については、次のセクションで説明します。

コンフィギュレーションファイルをコピー:
cp $(WRAPPER_HOME)/src/conf/wrapper.conf.in $(EXAMPLE_HOME)/conf/wrapper.conf

Wrapper コンフィギュレーションファイル

$(EXAMPLE_HOME)/conf/wrapper.conf」ファイルを「メモ帳」などのテキストエディタで開いてください。

以下の各プロパティを探して値を設定してください。

コンフィギュレーションファイル
wrapper.java.command=java
wrapper.java.command.loglevel=INFO

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=HelloWorldServer

wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../lib/classes

wrapper.java.library.path.1=../lib

wrapper.logfile=../logs/wrapper.log
  • wrapper.java.command]プロパティで、利用する Java コマンドの配置場所を指定します。 ここで指定した値は、システムパス上に検索されます。 また、絶対パスを指定することも可能です。

  • wrapper.java.command.loglevel]プロパティは任意設定ですが、Wrapper が生成する Java コマンドラインのデバッグに便利です。 最初の利用開始時には、何か問題が起きたときを考え、最短の解決に向けて、情報ログを含めることを推奨しますが、 一旦、アプリケーションが正しく動作するようになったら、このプロパティをコメントアウト(コメント記号で無効化)にすると良いでしょう。

  • wrapper.java.mainclass]プロパティで、起動したときに Java へ引き渡すメインクラスを指定します。 これが、新しいユーザーにとって、混乱する点の1つですが、 ほとんどの場合、これは Java アプリケーションのメインクラスではなく、Wrapper のヘルパークラスの1つになるでしょう。 Wrapper では、いくつかのインテグレーション方法をサポートしていますが、 この例にあるように、ここでは一番シンプルな方法 「インテグレーション方法1「WrapperSimpleApp」ヘルパークラス」を利用します。 このヘルパークラス[org.tanukisoftware.wrapper.WrapperSimpleApp]で JVM ライフサイクルや Wrapper とのバックエンド通信を管理します。 現時点では、この点について心配する必要はありません。

  • アプリケーション「HelloWorldServer」の実際のメインクラスは、[wrapper.app.parameter.1]プロパティを使って、最初のパラメータとして引き渡されます。 そのプロパティのナンバリングインデックスを使って、追加のパラメータとして「HelloWorldServer 」へ引き渡すことが可能です。 例えば、「wrapper.app.parameter.2=P1」です。

    ここでは示しませんが、[wrapper.java.additional.<n>]プロパティを使って、Java パラメータを追加することも可能です。

  • 次のステップは クラスパスの指定です。 [wrapper.java.classpath.<n>]プロパティを使って、クラスパスを指定します。 弊社のサンプルアプリケーションに2つのクラスパス指定が必要です。 1つ目は、Wrapper のヘルパークラスを含んでいる「wrapper.jar」ファイルで、 2つ目は、HelloWorldServer クラスが配置されている「lib/classes ディレクトリ」を含んでいるファイルです。

  • Wrapper では、いくつかの機能を実装するために、ネイティブライブラリーlibwrapper.so」を活用します。 多くのJavaアプリケーションでは、ネイティブライブラリーを利用しませんので、慣れていないかもしれませんが、[wrapper.java.library.path.<n>]プロパティでこれらのライブラリーが配置されている場所を指定します。 現時点では、この点について心配する必要はありません。

  • wrapper.logfile]プロパティで、ログファイルを書き出す場所を指定します。

以上で、Java アプリケーションをどのように動作させるのか、Wrapper に指示を出しました。

全てのプロパティ値を設定する際に、1つ注意しなければならない大切なことは、 常に、「wrapper.exe」バイナリの配置場所へ 相対参照のパスで指定してください。

シェルスクリプト

$(EXAMPLE_HOME)/bin/helloworldserver」シェルスクリプトファイルを「メモ帳」などのテキストエディターで開いてください。

ファイルの先頭辺りに2つの変数があります:「APP_NAME」と「APP_LONG_NAME」です。値をアプリケーション名前に置き換えてください。

シェルスクリプト
# Application
APP_NAME="helloworldserver"
APP_LONG_NAME="Hello World Server"

Wrapper をデーモンとして設定するのに便利な変数は他にもいくつかありますが、このチュートリアルでは後で説明します。

ターミナルで HelloWorldServer を動かす

これで Wrapper のセットアップは完了しました。 ここで設定したコンフィギュレーションをテストするためにターミナルで Wrapper を開始してみましょう。

新しくターミナルを開き、「cd」コマンドを使って、 自分の「$(EXAMPLE_HOME)」ディレクトリーに移動しましょう。 次のように、Wrapper とインテグレーションした Java アプリケーションを開始できます:

bin/helloworldserver console

コンフィギュレーションファイルの配置場所は Wrapper バイナリから相対的な位置にある点に注目してください。 これは直観に反しているように思えるかもしれませんが、異なる方法を使って起動するときに Wrapper の信頼性が非常に向上します。

Wrapper が開始すると、下記のような出力が表示されます:

wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | Java Service Wrapper Professional Edition 64-bit {version}
wrapper  |   Copyright (C) 1999-2010 Tanuki Software, Ltd. All Rights Reserved.
wrapper  |     http://wrapper.tanukisoftware.com
wrapper  |
wrapper  | --------------------------------------------------------------------
wrapper  | Java Service Wrapperに関心をお寄せいただき、ありがとうございます。
wrapper  |
wrapper  | トライアルライセンスキーで完全なフル機能として動作しており、
wrapper  | 何度でも好きなだけ、Java Service Wrapperを動作させたり
wrapper  | 再起動したりできます。Wrapperの各起動は自動的に
wrapper  | 15分後にシャットダウンします。
wrapper  |
wrapper  | この制限つきトライアルライセンスキーは、トライアルライセンスの
wrapper  | リスエストを提出する必要はなく、様々なマシン上で、素早くコンフィギュ
wrapper  | レーションテスト用に便利に使えます。さらに利用時間の延長が必要なら
wrapper  | すぐに1カ月の無料トライアルライセンスを取得することもできます:
wrapper  |   http://wrapper.tanukisoftware.com/trial
wrapper  |
wrapper  | Java Service Wrapper 利用を有効化するライセンスキーが必要です。
wrapper  | ライセンスキーは Java Service Wrapperウェブサイトで購入できます:
wrapper  |   http://wrapper.tanukisoftware.com/purchase
wrapper  |
wrapper  | 開発やテスト運用の目的で利用されているトライアルライセンスキー
wrapper  | のため、デプロイされたシステムの一部として利用できません。
wrapper  | --------------------------------------------------------------------
wrapper  | 
wrapper  | 
wrapper  | JVM起動中...
wrapper  | Java コマンドライン:
wrapper  |   Command[0] : /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
wrapper  |   Command[1] : -Djava.library.path=../lib
wrapper  |   Command[2] : -classpath
wrapper  |   Command[3] : ../lib/wrapper.jar:../lib/classes
wrapper  |   Command[4] : -Dwrapper.key=sSRU9TooPnyds7IrRI2rFtKRHEgc8E4A
wrapper  |   Command[5] : -Dwrapper.port=32000
wrapper  |   Command[6] : -Dwrapper.jvm.port.min=31000
wrapper  |   Command[7] : -Dwrapper.jvm.port.max=31999
wrapper  |   Command[8] : -Dwrapper.pid=8557
wrapper  |   Command[9] : -Dwrapper.version=3.5.32-pro
wrapper  |   Command[10] : -Dwrapper.native_library=wrapper
wrapper  |   Command[11] : -Dwrapper.arch=x86
wrapper  |   Command[12] : -Dwrapper.cpu.timeout=10
wrapper  |   Command[13] : -Dwrapper.jvmid=1
wrapper  |   Command[14] : org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper  |   Command[15] : HelloWorldServer
jvm 1    | WrapperManager: 初期化中...
jvm 1    | 接続受信ポート番号: 9000

ログ上部にあるバナーは、一時的にトライアルライセンスを利用しているために表示されています。 長時間トライアルライセンスのリクエスト、あるいは後で ライセンスの購入などをご案内しています。

その「Java コマンドライン:」に続く行は、Wrapper が JVM を起動させるときに使用するコマンドのすべての引数を示します。問題解決するときにとても役に立ちます。一旦、動作の開始を確認したら、ここで、[wrapper.java.command.loglevel]プロパティをコメントアウト(コメント記号で無効化)してください。 この例の残り部分は、コメントアウトしていると仮定しています。

ライセンスを購入された場合には、次のように見えるでしょう:

wrapper  | --> Wrapperがコンソールとして開始しました
wrapper  | Java Service Wrapper Professional Edition 64-bit {version}
wrapper  |   Copyright (C) 1999-2010 Tanuki Software, Ltd. All Rights Reserved.
wrapper  |     http://wrapper.tanukisoftware.com
wrapper  |   {licensee}へライセンスを割り当て
wrapper  |
wrapper  | JVM起動中...
jvm 1    | WrapperManager: 初期化中...
jvm 1    | 接続受信ポート番号: 9000

[CTRL]+[C]のキー操作でいつでもアプリケーションを停止することができます。 Wrapper は、「なぜアプリケーションが停止されたのか」常に記録を取りますので、 次のようなログ記録で確認することができます。

wrapper  | CTRL-C trapped.  Shutting down.
wrapper  | <-- Wrapper Stopped

HelloWorldServer をデーモンとして動かす

Wrapper のコンフィギュレーションが正しく検証されれば、 次は Wrapper をデーモンとしてインストールできる段階です。

デーモンをインストール

次のように、Wrapper に「-i」コマンドを使うことで、インストールできます。

sudo bin/helloworldserver install

注意

ルートユーザーである必要がありますのでご注意ください。

デーモンが無事にインストールされると次のような出力が表示されます。

Detected Ubuntu or Debian:
Installing the Hello World Server Application daemon using systemd...
creating default service file...
Created symlink from /etc/systemd/system/multi-user.target.wants/testwrapper.service to /etc/systemd/system/testwrapper.service.

注意

ご利用 OS やデーモンのインストールに使用されたサービス管理ツールによっては、メッセージが異なる場合があります。このページで以下に示されている他のコマンドも同じです。

デーモンを開始

再度ルートユーザーとしてシェルスクリプトファイルを使用してデーモンを開始することができます。

sudo bin/helloworldserver install

デーモンが正常に開始されると以下のような出力が表示されるはずです:

Waiting for Hello World Server Application...
running: PID:17548

これは、スクリプトが実際にデーモンを起動するように init システムに要求して、プロセスが実行されていることを検出するまで待機してから PID を出力することを示しています。 その後、ターミナルは他のコマンドを入力させますが、Wrapper はまだバックグラウンドで実行されます。

ログファイルを開く、或いは「status」コマンドを使用することで Wrapper が実行されているかを確認出来ます。

$ bin/helloworldserver status
Hello World Server Application (installed with systemd) is running: PID:17548, Wrapper:STARTED, Java:STARTED

これは、Wrapper が正常に開始し、Java アプリケーションを起動したことを示しています。

インストールと同時にデーモンを開始

バージョン 3.5.28より、スクリプトは一度にインストールと起動の両方を実行する「installstart」コマンドが使えるようになりました。

sudo bin/helloworldserver installstart

デーモンが正常にインストール及び開始されると以下のような出力が表示されるはずです:

Detected Ubuntu or Debian:
Installing the Test Wrapper Sample Application daemon using systemd...
creating default service file...
Created symlink from /etc/systemd/system/multi-user.target.wants/testwrapper.service to /etc/systemd/system/testwrapper.service.
Waiting for Test Wrapper Sample Application...
running: PID:20720

デーモンを停止

デーモンを停止する準備ができましたら、シェルスクリプトファイルの「stop」コマンドをルートユーザーとして実行すると停止できます。

sudo bin/helloworldserver stop

status」コマンドを使用し、Wrapper が実行されているかどうか確認できます:

$ bin/helloworldserver status
Hello World Server (installed with systemd) is not running.

デーモンを再起動

デーモンは、「restart」若しくは「condrestart」コマンドで再起動できます。「restart」はデーモンが既に実行されている場合、デーモンを停止してから再起動させます。デーモンが実行されていない場合、このコマンドはデーモンを起動させます。「condrestart」はデーモンが実行されている場合のみに再起動させます。

sudo bin/helloworldserver restart
sudo bin/helloworldserver condrestart

デーモンを一時停止・再開

バージョン 3.5.31より、Wrapper はシェルスクリプトを使用し、一時停止及び再開できるようになりました。ただし、事前にポーザブル( 一時停止可)に設定する必要がありますのでスクリプト上部にある「#PAUSABLE=true」行のコメントを有効に(コメント記号を削除)します。このプロパティを有効にするにはデーモンを再起動する必要があります。

PAUSABLE=true

スクリプトにある「#PAUSABLE_MODE=signals」行はデーモンを一時停止や再開するモードを設定できます。現在は二つのモードが利用可能です:

- 「signals」は、SIGUSR1SIGUSR2 を使用して Wrapper に一時停止と再開アクションを示します。

- 「file」は、command file を使用します。

デフォルト値は「signals」で、コマンドファイルのパーミッションを気にすることなく、より速く及び安全に実行できます。

PAUSABLE_MODE=signals

Wrapper を起動し、「pause」コマンドを実行します。次のような出力が表示されます。

$ bin/helloworldserver pause
Pausing Hello World Server.

status」コマンドで Wrapper が一時停止したことを確認できます:

$ bin/helloworldserver status
Hello World Server (installed with systemd) is running: PID:7050, Wrapper:PAUSED, Java:DOWN_CLEAN

これでは、「resume」コマンドを使ってアプリケーションを再開します:

$ bin/helloworldserver resume
Resuming Hello World Server.

status」コマンドを使用し、Wrapper が再度実行されていることを確認します:

$ bin/helloworldserver status
Hello World Server (installed with systemd) is running: PID:7050, Wrapper:PAUSED, Java:DOWN_CLEAN

デーモンをアンインストール

Wrapper は、システムがリブートするときに再起動するよう設定されています。 これはテストですので、下記のようにデーモンを削除するのが望ましいです。

sudo bin/helloworldserver remove

デーモンが正常にアンインストールされると以下のような出力が表示されます:

sudo bin/testwrapper remove
Detected Ubuntu or Debian:
Stopping Test Wrapper Sample Application...
Test Wrapper Sample Application was not running.
Removing Test Wrapper Sample Application daemon from systemd...
Removed symlink /etc/systemd/system/multi-user.target.wants/testwrapper.service.

アンインストールする前にスクリプトは Wrapper が実行されていない事を確認します。

アンインストール後、「status」コマンドは下記を表示すべきです:

$ bin/helloworldserver status
Hello World Server (not installed) is not running.

サービス管理ツールを選択

プラットフォームにより、デーモンがインストールおよび実行するときに使用できる異なるシステムがあります。 例えば、Linux 上では systemd、upstart と initd がよく使われます。 AIX 上では、デーモンは SRC または initd のいずれかでインストールできます。

以下の表は、プラットフォームに応じて Wrapper がデーモンをインストールするために使用する様々なサービス管理ツールの概要を示しています。上部に記載されているものは、より高度な機能で一般的に好ましいものです。

Linux

AIX

MacOSX

FreeBSD
その他の UNIX プラットフォーム
SystemdSrcLaunchdrc.dInit.d
UpstartInit.d
Init.d

ディストリビューション(Linux)、OS のバージョン、および OS の設定によっては、上記のサービス管理ツールの一部がインストールされていない場合があります。 ただし、Wrapper のシェルスクリプトには、どのサービス管理ツールがマシン上に存在するかを検出する機能があります。 特定の OS(Linux や AIX など)でいくつかのツールが利用可能な場合、Wrapper は自動的お勧めのツールを優先順位の高いものを選択します。 たとえば、Linux では systemd は upstart より優先され、それもさらに initd よりも優先されます。 このデフォルト動作はバージョン3.5.31で導入され、スクリプトの先頭近くにある次の行によって構成されます:

SERVICE_MANAGEMENT_TOOL=auto

Wrapper によって自動的に選択されたものとは別のサービス管理ツールを明示的に指定したい場合があります。この場合、上記プロパティーを別のシステム名で設定します。

SERVICE_MANAGEMENT_TOOL=initd

注意

このプロパティを有効にするにはデーモンを再インストールする必要があります。

サービス再起動後、以下のような出力が表示されるはずです:

$ sudo bin/helloworldserver install
Detected Ubuntu or Debian:
Installing the Hello World Server daemon using init.d..
 Adding system startup for /etc/init.d/helloworldserver ...
   /etc/rc0.d/K20helloworldserver -> ../init.d/helloworldserver
   /etc/rc1.d/K20helloworldserver -> ../init.d/helloworldserver
   /etc/rc6.d/K20helloworldserver -> ../init.d/helloworldserver
   /etc/rc2.d/S20helloworldserver -> ../init.d/helloworldserver
   /etc/rc3.d/S20helloworldserver -> ../init.d/helloworldserver
   /etc/rc4.d/S20helloworldserver -> ../init.d/helloworldserver
   /etc/rc5.d/S20helloworldserver -> ../init.d/helloworldserver

そのあと、デーモンは次回起動する際に initd を使用します。

警告

指定されたサービス管理ツールはシステム内に既存しない、若しくは何らかの理由でインストールに失敗した場合、シェルスクリプトはエラーコード1を返します。

テスト終了後、次回のシステムブートで起動されないように、デーモンをインストールすることを忘れないでください。

参照: Wrapper でアプリケーションを起動する