2009-09-28 33 views
11

Tôi muốn xác định trạng thái thoát của quy trình trong suốt thời gian chạy móc ngắt.Xác định trạng thái thoát trong chuỗi móc tắt máy java

Tôi muốn có một logic mà là dựa trên các mã trạng thái (0 hoặc nonzero)

(ví dụ: nếu không làm gì khác khác không gửi email cảnh báo)

Bạn có biết làm thế nào tôi có thể có được thông tin này?

Trả lời

6

Tôi đã cố gắng ghi đè phương thức SecurityManagercheckExit(int status) - điều này hoạt động nếu System.exit(status) được gọi ở bất kỳ đâu - tuy nhiên, nó không đặt trạng thái khi ứng dụng thoát "bình thường" (không có chuỗi hoạt động) hoặc lỗi. .

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

} 
0

Bạn phải lưu trạng thái thoát trong main thành biến toàn cầu (public static).

+1

Tại sao cụ thể là biến tĩnh công khai trong chính? Không thể tình trạng thoát được chuyển đến đối tượng hoạt động như móc đóng trước khi gọi System.exit? – Adamski

+0

Biến toàn cầu chỉ là giải pháp đơn giản nhất. –

2

Dưới đây là một số mã mẫu trong đó một lớp chuyên dụng được sử dụng để thực hiện cuộc gọi System.exit qua cuộc gọi đến doExit(int). Lớp này cũng lưu trữ trạng thái thoát và sau đó hoạt động như một cái móc đóng.

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 ... 
     } 
    } 
    } 
} 
+0

Có gói phương thức thoát và sử dụng nó trên mã ứng dụng là một tùy chọn nhưng không phải là tốt nhất! Tôi đã mong đợi một tài sản exitStatus được cung cấp bởi các sdk java mặc dù có vẻ như nó không có sẵn. – Kostas

1

Tại sao điều này trong ứng dụng của nó? Nếu ứng dụng của bạn không gửi một e-mail như là một phần của hoạt động bình thường, việc kết hợp loại chức năng này không phải là một ý tưởng hay, IMHO.

Tôi sẽ chỉ tin tưởng thiết lập một giá trị trả về thích hợp từ quy trình JVM và để cho một tập lệnh shell hoặc bất cứ điều gì chăm sóc việc tạo điều kiện của e-mail.

Shutdownhook chỉ được chạy trong một thời gian ngắn, việc gửi e-mail có thể tốn khá nhiều thời gian.

+0

Tôi đồng ý. Điều kiện này nên được ra khỏi codebase ứng dụng và một cái gì đó bên ngoài có thể chăm sóc cảnh báo email. Ứng dụng chạy trên hộp NT dưới dạng dịch vụ sử dụng phiên bản cộng đồng đóng gói tanuki. Trình bao bọc cung cấp thông báo qua email nhưng chỉ trong phiên bản trả tiền của nó. Bạn có biết cấu hình nguồn mở miễn phí có thể quản lý thông báo qua email không? – Kostas

Các vấn đề liên quan