12

シャットダウンフックの実行時にプロセスの終了ステータスを確認したいと思います。

ステータスコード(0またはゼロ以外)に基づくロジックが必要です

(例:ゼロの場合は他に何もしません非ゼロはアラートメールを送信します)

この情報を入手する方法を知っていますか?

4

4 に答える 4

7

SecurityManager checkExit(int status)メソッドをオーバーライドしようとしました-これSystem.exit(status)は明示的にどこかで呼び出された場合に機能します-しかし、アプリケーションが「正常に」終了したとき(アクティブなスレッドがないとき)にステータスが設定されないか、エラーによってVMが強制終了されます。

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);
        }
    }

}
于 2009-09-28T13:45:25.620 に答える
3

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 ...
      }
    }
  }
}
于 2009-09-28T12:25:22.433 に答える
1

なぜアプリケーションitsellfでこれを行うのですか?アプリケーションが通常の操作の一部として電子メールを送信していない場合、この種の機能を組み込むことはお勧めできません、IMHO。

私は、JVMプロセスから適切な戻り値を設定し、シェルスクリプトなどに電子メールの条件付き作成を処理させることを信頼します。

シャットダウンフックは短時間だけ実行されることになっているため、電子メールの送信にはかなりの時間がかかる可能性があります。

于 2009-09-28T12:57:59.037 に答える
-1

main終了ステータスをグローバル(public static)変数に保存する必要があります。

于 2009-09-28T12:06:30.777 に答える