Javaのシャットダウンフックのスレッド内で終了ステータスを決定します
-
18-09-2019 - |
質問
私は、シャットダウンフックの実行中のプロセスの終了ステータスを決定したいと思います。
Iステータスコード(0またはゼロ以外)に基づいているロジックを持ちたい
(例:ゼロ他に何もしないゼロ以外のアラートメールを送信する場合)
私は、この情報を得ることができる方法を知っていますか?
解決
私はSecurityManager
のcheckExit(int status)
メソッドをオーバーライドしようとした - しかし、アプリケーションの終了時に、それは(なしアクティブなスレッド)「は、通常」ステータスを設定していない、またはエラーがVMを殺す - これはSystem.exit(status)
はどこにでも明示的に呼び出された場合に動作します。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.Permission;
public class ExitChecker {
public ExitChecker() {
System.setSecurityManager(new ExitMonitorSecurityManager());
Runtime.getRuntime().addShutdownHook(new Thread(new MyShutdownHook()));
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while (!line.equalsIgnoreCase("Q")) {
try {
System.out.println("Press a number to exit with that status.");
System.out.println("Press 'R' to generate a RuntimeException.");
System.out.println("Press 'O' to generate an OutOfMemoryError.");
System.out.println("Press 'Q' to exit normally.");
line = input.readLine().trim();
processInput(line);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
private void processInput(String line) {
if (line.equalsIgnoreCase("Q")) {
// continue, will exit loop and exit normally
} else if (line.equalsIgnoreCase("R")) {
throwRuntimeException();
} else if (line.equals("O")) {
throwError();
} else {
// try to parse to number
try {
int status = Integer.parseInt(line);
callExit(status);
} catch(NumberFormatException x) {
// not a number.. repeat question...
System.out.println("\nUnrecognized input...\n\n");
}
}
}
public void callExit(int status) {
System.exit(status);
}
public void throwError() {
throw new OutOfMemoryError("OutOfMemoryError");
}
public void throwRuntimeException() {
throw new RuntimeException("Runtime Exception");
}
public static void main(String[] args) {
new ExitChecker();
}
private static class ExitMonitorSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
@Override
public void checkPermission(Permission perm, Object context) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
@Override
public void checkExit(int status) {
System.out.println("Setting exit value via security manager...");
MyShutdownHook.EXIT_STATUS = status;
}
}
private static class MyShutdownHook implements Runnable {
public static Integer EXIT_STATUS;
public void run() {
System.out.println("In MyShutdownHook - exit status is " + EXIT_STATUS);
}
}
}
他のヒント
ここでは、専用のクラスはSystem.exit
への呼び出しを介してdoExit(int)
コールを開始するために使用されるいくつかの例のコードです。クラスはまた、終了ステータスを格納し、続いてシャットダウンフックとして機能する。
public class ShutDownHook implements Runnable {
private volatile Integer exitStatus;
// Centralise all System.exit code under control of this class.
public void doExit(int exitStatus) {
this.exitStatus = exitStatus;
System.exit(exitStatus); // Will invoke run.
}
public void run() {
// Verify that an exit status has been supplied.
// (Application could have called System.exit(int) directly.)
if (this.exitStatus != null) {
switch(exitStatus) {
case 0: // Process based on exit status.
// Yada yada ...
}
}
}
}
なぜアプリケーションitsellfでこれを行いますか?アプリケーションは、通常の業務の一環として、電子メールを送信していない場合、この種の機能を組み込むことは良いアイデアで、私見ではありません。
私は、JVMプロセスからの適切な戻り値を設定することに信頼し、シェルスクリプトまたは任意の電子メールの条件付き作成の世話を聞かせます。
Shutdownhooksはかなりの時間を消費することができ、電子メールを送信し、短時間だけ実行することになっています。
あなたはグローバル(main
)変数にpublic static
で終了ステータスを保存する必要があります。
所属していません StackOverflow