سؤال

أرغب في تحديد حالة الخروج من العملية أثناء وقت تشغيل Shutdown Hook.

أريد أن يكون منطقا يعتمد على رمز الحالة (0 أو غير صفري)

(على سبيل المثال: إذا لم تفعل صفر لا شيء آخر غير صفري إرسال رسالة بريد إلكتروني تنبيه)

هل تعرف كيف يمكنني الحصول على هذه المعلومات؟

هل كانت مفيدة؟

المحلول

حاولت تجاوز 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);
        }
    }

}

نصائح أخرى

فيما يلي بعض البرمجية مثال حيث يتم استخدام فئة مخصصة لبدء 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؟ إذا كان التطبيق الخاص بك لا يرسل رسائل بريد إلكتروني كجزء من العمليات العادية، فإن دمج هذا النوع من الوظائف ليست فكرة جيدة، IMHO.

أود أن أثق فقط في تحديد قيمة إرجاع مناسبة من عملية JVM واترك نص شل أو أيا كان العناية بالإنشاء الشرطي للبريد الإلكتروني.

من المفترض أن يتم تشغيل ShutDownHooks لفترة قصيرة فقط، وإرسال بريد إلكتروني يمكن أن تستهلك بعض الوقت.

يجب عليك حفظ حالة الخروج في main في عالمي (public static) عامل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top