2009-02-13 20 views
49

से लॉन्च की गई प्रक्रिया पर निष्पादित करने के लिए शट डाउन हुक कैसे प्राप्त करें मेरे पास मेरे एप्लिकेशन में शटडाउन हुक है (Runtime.getRuntime().addShutdownHook का उपयोग करके बनाया गया है)। हालांकि अगर मैं ग्रहण के भीतर से एप्लिकेशन लॉन्च करता हूं, तो शट डाउन हुक निष्पादित होने पर इसे बंद कर दिया जाता है।ग्रहण

मुझे लगता है कि ऐसा इसलिए है क्योंकि ग्रहण प्रक्रिया के लिए एक बल-हत्या संकेत के बराबर भेजता है, जो शट-डाउन हुक निष्पादित नहीं करता है (विंडोज़ पर टास्ककिल/एफ के बराबर या लिनक्स पर मार-पी) हालांकि, मुझे बिल्कुल यकीन नहीं है।

क्या किसी को पता है कि इस के आसपास कैसे जाना है? मैं विंडोज़ (Vista) चला रहा हूं, और मुझे लगता है कि यह एक विंडोज-विशिष्ट मुद्दा हो सकता है, लेकिन मुझे यकीन नहीं है।

+0

ग्रहण के भीतर से अपने एप्लिकेशन को चलाने के नहीं है? –

+0

मुझे लगता है कि @ मैटब का सुझाव अच्छा है, क्योंकि अधिकांश कार्यक्रमों को किसी बिंदु पर आईडीई के बाहर भागना चाहिए। वैसे, इंटेलिजे आईडीईए के लिए एक बटन है: http://stackoverflow.com/questions/4727536/। –

+2

@ टिमबुथ, अच्छा लेकिन उपयोगी नहीं है जब हम तेजी से कोड-टेस्ट-डीबग-कोड-टेस्ट-डीबग चक्र कर रहे हैं ... – Pacerier

उत्तर

1

मुझे यकीन नहीं है कि इसे कैसे ठीक किया जाए लेकिन इंटेलिजे ने अपने 'रन' संवाद में एक अलग बटन जोड़ा जो वीएम को शटडाउन हुक कहता है। उनके डीबगर में यह सुविधा नहीं है।

11

सबसे पहले, क्या आपका आवेदन समाप्त हो रहा है या आप जबरन इसे समाप्त कर रहे हैं? यदि आप जबरन इसे समाप्त कर रहे हैं (स्टॉप बटन के माध्यम से), तो Eclipse bug report में विवरण है कि यह क्यों काम नहीं कर रहा है।

विफल होने के कारण, आप विंडोज-विशिष्ट व्यवहार होने के बारे में सही हो सकते हैं। मैं मैक पर हूं इसलिए मैं पुष्टि नहीं कर सकता, क्षमा करें। हालांकि, मैं आपको बता सकता हूं कि निम्नलिखित परीक्षण कार्यक्रम अपेक्षित के रूप में शटडाउन हुक निष्पादित करता है।

public class MyShutdownHook 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("Entering main."); 

     Runtime.getRuntime().addShutdownHook( 
      new Thread(
       new Runnable() { 
        public void run() { 
         System.out.println("Shutdown hook ran."); 
        } 
       } 
      ) 
     ); 

     System.out.println("Exiting main."); 
    } 
} 

Runtime#addShutdownHook के लिए Javadocs उल्लेख है कि बंद हुक नहीं चला जब JVM, निरस्त किया गया है सामान्य रूप से बाहर निकल गया नहीं है, तो फिर, तो आप शायद अपनी मान्यताओं में सही हैं। कहा जा रहा है, कोशिश करने के लिए कुछ चीजें हैं। दोबारा, खेद है कि मैं इन समय की पुष्टि नहीं कर सकता - यहां कोई विंडोज नहीं है। (Blessedly!)

  • यकीन है कि JVM -Xrs विकल्प शामिल नहीं है सुनिश्चित करें। शटडाउन हुक पर side-effect है।
  • -server या -client विकल्प का उपयोग कर JVM लॉन्च करने का प्रयास करें। यह मेरा अनुभव रहा है कि वीएम मोड की पसंद से एज-केस व्यवहार प्रभावित किया जा सकता है। (विशेष रूप से थ्रेडिंग के संबंध में - कम से कम मैक पर।)
  • क्या आप अपने ऐप को प्रोफाइलर या पसंद के तहत लॉन्च कर रहे हैं? किसी भी देशी पुस्तकालय लोड हो रहा है?
  • क्या आपको कुछ घातक त्रुटि मिल रही है और इसे याद आ रही है? उदा।, आउटऑफमेमरी त्रुटि या पसंद है?
  • को जांचने/अनचेक करने का प्रयास करें अपने अनुप्रयोग के से पृष्ठभूमि विकल्प लॉन्च करें ग्रहण में कॉन्फ़िगरेशन चलाएं।
  • अंतिम लेकिन कम से कम नहीं: सिस्टम.एक्सिट() मैन्युअल रूप से यदि आपके पास अवसर है तो आमंत्रित करें। :)
+1

आप -Xrs विकल्प को खोजने के लिए कैसे जानते थे? – Pacerier

0

मैं इस समय वेबस्पेयर में फंस गया हूं, और यह नहीं देख रहा कि मैं क्या देख रहा हूं। लेकिन मुझे एक ही वीएम में एप्लिकेशन लॉन्च करने से संबंधित एक रन कॉन्फ़िगरेशन विकल्प रखने वाले ग्रहण को याद है। क्या यह संभव है कि आप अपने जावा एप्लिकेशन को उसी वीएम में ग्रहण वीएम के रूप में लॉन्च करना संभव है?

लेकिन विकल्प मेरे दिमाग को फिसलता है।

if (Boolean.parseBoolean(System.getenv("RUNNING_IN_ECLIPSE"))) { 
    System.out.println("You're using Eclipse; click in this console and " + 
      "press ENTER to call System.exit() and run the shutdown routine."); 
    try { 
     System.in.read(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    System.exit(0); 
} 
23

मैं इस समस्या से बचने के लिए अपने मुख्य विधि के अंत में निम्नलिखित हैक इस्तेमाल किया मार डालते हैं।

#!/bin/bash 
set -o nounset        # Treat unset variables as an error 

PROCESSES=$(ps axo pid,ppid,command) 

# Find eclipse launcher PID 
LAUNCHER_PID=$(echo "$PROCESSES" | grep "/usr/lib/eclipse/eclipse" |grep -v "launcher"|awk '{print $1}') 
echo "Launcher PID $LAUNCHER_PID" 

# Find eclipse PID 
ECLIPSE_PID=$(echo "$PROCESSES" | egrep "[[:digit:]]* $LAUNCHER_PID " | awk '{print $1}') 
echo "Eclipse PID $ECLIPSE_PID" 

# Find running eclipse sub-process PIDs 
SUB_PROCESS=$(echo "$PROCESSES" | egrep "[[:digit:]]* $ECLIPSE_PID " | awk '{print $1}') 

# List processes 
echo 
for PROCESS in $SUB_PROCESS; do 
    DRIVER=$(ps --no-headers o pid,ppid,command $PROCESS | awk '{print $NF}') 
    echo "$PROCESS $DRIVER" 
done 

echo "Kill a process using: 'kill -SIGTERM \$PID'" 
+5

नोट: आपको रन कॉन्फ़िगरेशन में मैन्युअल रूप से पर्यावरण चर "RUNNING_IN_ECLIPSE" जोड़ना होगा, और मान को TRUE पर सेट करना होगा। –

+0

या आप केवल डीबगिंग के उद्देश्य के लिए लाइनों के बिना/तो कर सकते हैं। –

+0

यह समाधान काम नहीं करता है अगर हम ** कंसोल ** ऐप पर "शटडाउन" का परीक्षण करना चाहते हैं जो आधा रास्ते चल रहा है। – Pacerier

5

यहाँ एक स्क्रिप्ट है कि आप उपलब्ध प्रक्रियाओं को सूचीबद्ध करने के ग्रहण के तहत है कि आप कर सकते थे चल ग्रहण के बाहर चला सकते हैं क्या है:

+0

हम्म, लेकिन इसे मारना उतना ही जबरन इसे रोकने के समान है? इस प्रकार, शट डाउन हुक नहीं चलेंगे। – Pacerier

+1

@Pacerier आप किस सिग्नल का उपयोग करते हैं इस पर निर्भर करता है। डिफ़ॉल्ट टीईआरएम है जो शट डाउन हुक चलाएगा। 'kill -9' शट डाउन हुक नहीं चलाएगा। अधिक जानकारी: http://superuser.com/questions/107543/bash-man-page-kill-pid-vs-kill-9-pid –

0

साईराम यहीं है, बुला System.exit (0) हम ग्रहण JVM समाप्त कर सकते हैं और बंद हुक परिणाम

0

विंडोज़ पर देखने शान से एक मानक तरीके से एक जावा आवेदन को रोकने के लिए कर सकते हैं कर आप Ctrl + सी भेजने की आवश्यकता है। यह केवल कंसोल ऐप्स के साथ काम करता है, लेकिन ग्रहण java.exe के बजाय javaw.exe का उपयोग करता है। इसे हल करने के लिए लॉन्च कॉन्फ़िगरेशन, जेआरई टैब खोलें और "वैकल्पिक जेआरई:" चुनें। "जावा निष्पादन योग्य" समूह बॉक्स प्रकट होता है और वैकल्पिक निष्पादन योग्य "जावा" में प्रवेश करने की अनुमति देता है।

अब हमें एक छिपे हुए कंसोल के साथ एक प्रक्रिया में Ctrl-C भेजने के लिए एक बाहरी प्रोग्राम की आवश्यकता है। मुझे here और here संकेत मिले। हमारा कार्यक्रम वांछित प्रक्रिया के कंसोल से जुड़ा हुआ है और कंसोल घटना भेजता है।

#include <stdio.h> 
#include <windows.h> 

int main(int argc, char* argv[]) 
{ 
    if (argc == 2) { 
     unsigned pid = 0; 
     if (sscanf_s(argv[1], "%u", &pid) == 1) { 
      FreeConsole(); // AttachConsole will fail if we don't detach from current console 
      if (AttachConsole(pid)) { 
       //Disable Ctrl-C handling for our program 
       SetConsoleCtrlHandler(NULL, TRUE); 
       GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); 
       return 0; 
      } 
     } 
    } 

    return 1; 
} 

टेस्ट जावा कार्यक्रम: ग्रहण में

C:\>killsoft.exe 10520 

टेस्ट कार्यक्रम उत्पादन:

public class Shuthook { 

    public static void main(final String[] args) throws Exception { 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
      @Override 
      public void run() { 
       System.out.println("Shutting down..."); 
      } 
     }); 

     String sPid = ManagementFactory.getRuntimeMXBean().getName(); 
     sPid = sPid.substring(0, sPid.indexOf('@')); 

     System.out.println("pid: " + sPid); 
     System.out.println("Sleeping..."); 
     Thread.sleep(1000000); 
    } 

} 

यह समाप्त

pid: 10520 
Sleeping... 
Shutting down...