Linuxでは、次のコマンドを実行できます。
service <someService> start
service <someService> stop
kill -9 <someService>
でプロセスを強制終了するのとは対照的です。以前の質問で学んだように、これはプロセスにSIGTERM
(前)とSIGKILL
(後)を送信することの違いです。
では、通常のJARまたはWARを、これらのコマンドで開始および停止できるサービス/デーモンとして「登録」(およびコーディング)するにはどうすればよいでしょうか。 JavaにはSIGTERM
sを処理するためのAPIが必要だと思いますか?
前もって感謝します!
シャットダウン固有のコードを実行したいだけの場合、これを処理する「適切なJava」の方法ではシグナルを使用せず、代わりに、アプリケーションが終了しようとしたときに実行される汎用の「シャットダウンフック」を追加します。これは、Javaが時々苦しむ最小公分母の問題の1つです。(すべてのプラットフォームがSIGINT
をサポートしているわけではないため、JavaではSIGINT
をサポートしているプラットフォームはありません。)
残念ながら、 ShutdownHook
ではあまりコンテキストを取得できませんが、それでも役立つ場合があります。
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run()
{
// cleanup
}
}));
受信したシグナルを本当に区別する必要がある場合、Javaが通常無視するシグナル(USR1
など)をサポートする場合、またはシグナルに基づいてシャットダウンを中止する場合、残念ながら、ShutdownHook
はほとんど役に立たないでしょう。
Sun.misc.SignalHandler
クラスを使用して、Sun JVMでシグナルをキャプチャするための、サポートされていない、十分に文書化されていない方法があります。 IBM JVMもこれをサポートしている のようですが、これは疑わしいほど移植性があります。
たとえば、シグナルハンドラーを接続して、サーバー構成のSIGHUP
リロードをリロードできます。サーバー構成は、init.d
スクリプトでreload
動詞として設定されています。
Signal.handle(new Signal("HUP"), new SignalHandler() {
public void handle(Signal signal)
{
reloadConfiguration();
}
});
Javaアプリケーションをsystem
コマンドを使用して制御するように構成するには、それを起動するinit.d
プログラムでシェルスクリプトを作成する必要があります。これは、単にstart
に応答する必要があります。 stop
動詞を入力し、適切なアクションを実行します。たとえば、これは/etc/init.d/my-Java-program
の場合があります。
#!/bin/sh
case "$1" in
start)
Java /path/to/my/Java/program.jar &
echo $! > /var/run/my-Java-program.pid
;;
stop)
if [ ! -f /var/run/my-Java-program.pid ]; then
echo "my-Java-program: not running"
exit 1
fi
kill -TERM `cat /var/run/my-Java-program.pid`
;;
reload)
if [ ! -f /var/run/my-Java-program.pid ]; then
echo "my-Java-program: not running"
exit 1
fi
kill -HUP `cat /var/run/my-Java-program.pid`
;;
*)
echo "Usage: /etc/init.d/my-Java-program {start|stop|reload}"
exit 1
;;
esac
exit 0
これで、/etc/init.d/my-Java-program start
を実行してアプリケーションを起動できます。または、CentOSでは、サービスmy-Java-programstart`を使用することもできます。
ネイティブUnixプログラムのように、純粋なJavaでさまざまなシグナルのシグナルハンドラーを定義することはできません。これは、たとえば、の一般的な規則に従うことができないことを意味します。プログラムにSIGHUP
で構成を再ロードさせ、SIGINT
またはSIGTERM
でクリーンシャットダウンを実行させます。
あなたができることは シャットダウンフック を定義することです。これらは、仮想マシンがシャットダウンするときに実行されます。 SIGTERM
を受け取った後。次に例を示します。
Runnable myShutdownHook = new Runnable() {
void run() {
System.out.println("I'm melting! What a world...");
}
};
Runtime.getRuntime().addShutdownHook(new Thread(myShutdownHook));