2009-09-28 13 views
11

के भीतर निकास स्थिति निर्धारित करें मैं शटडाउन हुक रनटाइम के दौरान प्रक्रिया की निकास स्थिति निर्धारित करना चाहता हूं।जावा शटडाउन हुक थ्रेड

मैं

एक तर्क जो स्थिति कोड (0 या अशून्य) पर आधारित है करना चाहते हैं (उदाहरण: यदि शून्य और कुछ नहीं कर अशून्य एक चेतावनी ईमेल भेजने के लिए)

तुम्हें पता है मैं कैसे कर सकते हैं करते हैं यह जानकारी प्राप्त करें?

उत्तर

6

मैं SecurityManagercheckExit(int status) विधि ओवरराइड करने की कोशिश की - यह काम करता है अगर 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); 
     } 
    } 

} 
0

आपको main में बाहर निकलने की स्थिति को वैश्विक (public static) चर में सहेजना होगा।

+1

मुख्य रूप से मुख्य रूप से सार्वजनिक स्थिर चर क्यों? System.exit को कॉल करने से पहले शट-डाउन हुक के रूप में कार्य करने वाली ऑब्जेक्ट पर बाहर निकलने की स्थिति को पारित नहीं किया जा सका? – Adamski

+0

वैश्विक चर सिर्फ सबसे सरल समाधान है। –

2

यहां कुछ उदाहरण कोड है जिससे कॉल को 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 ... 
     } 
    } 
    } 
} 
+0

हां बाहर निकलने की विधि को लपेटना और एप्लिकेशन कोड में इसका उपयोग करना एक विकल्प है लेकिन सबसे अच्छा नहीं है! मैं एक एक्स्टास्टैटस संपत्ति की अपेक्षा कर रहा था जो जावा एसडीके द्वारा प्रदान की जाती है हालांकि ऐसा लगता है कि यह उपलब्ध नहीं है। – Kostas

1

एप्लिकेशन में यह क्यों है? यदि आपका एप्लिकेशन सामान्य संचालन के हिस्से के रूप में ई-मेल नहीं भेज रहा है, तो इस प्रकार की कार्यक्षमता को शामिल करना एक अच्छा विचार नहीं है, आईएमएचओ।

मैं सिर्फ जेवीएम प्रक्रिया से उपयुक्त वापसी मूल्य निर्धारित करने पर विश्वास करता हूं और एक शेल स्क्रिप्ट या जो भी ई-मेल की सशर्त निर्माण की देखभाल करता है।

शटडाउनहुक केवल थोड़े समय के लिए दौड़ने वाले हैं, एक ई-मेल भेजने में काफी समय लग सकता है।

+0

मैं सहमत हूं। यह स्थिति एप्लिकेशन कोडबेस से बाहर होनी चाहिए और कुछ बाहरी ईमेल अलर्ट का ख्याल रख सकता है। एप्लिकेशन एनटी बॉक्स पर तनुकी रैपर समुदाय संस्करण का उपयोग कर सेवा के रूप में चलता है। रैपर ईमेल अधिसूचनाएं प्रदान करता है लेकिन केवल अपने भुगतान संस्करण में। क्या आप एक मुक्त/खुली सोर्स की गई कॉन्फ़िगरेशन से अवगत हैं जो ईमेल सूचनाएं प्रबंधित कर सकता है? – Kostas

संबंधित मुद्दे