इनायत से जावा प्रक्रिया को कैसे रोकें?


88

मैं कैसे लिनक्स और विंडोज में एक जावा प्रक्रिया को इनायत से रोक सकता हूं?

कब Runtime.getRuntime().addShutdownHookबुलाया जाता है, और कब नहीं?

फाइनल करने वालों के बारे में क्या वे यहां मदद करते हैं?

क्या मैं किसी शेल से जावा प्रोसेस के लिए किसी तरह का सिग्नल भेज सकता हूं?

मैं अधिमानतः पोर्टेबल समाधान की तलाश कर रहा हूं।


तुम सच में परिभाषित करना चाहिए कि तुम क्या मतलब है। (कृपया)
हेनरी बी

7
मुझे लगता है कि वे मतलब है कि वे एक संसाधन को साफ करने का मौका दिया जाना चाहते हैं, रिलीज, ताले, और प्रोग्राम को मारने से पहले डिस्क पर किसी भी लगातार डेटा फ्लश करने के लिए।
स्टीव जी

जवाबों:


82

शटडाउन हुक सभी मामलों में निष्पादित होते हैं जहां वीएम जबरन नहीं मारा जाता है। इसलिए, यदि आपको "मानक" मार ( SIGTERMएक मार कमान से) जारी करना था, तो वे निष्पादित करेंगे। इसी तरह, वे कॉल करने के बाद निष्पादित करेंगे System.exit(int)

हालाँकि एक कठिन मार ( kill -9या kill -SIGKILL) तब वे निष्पादित नहीं करेंगे। इसी तरह (और स्पष्ट रूप से) वे निष्पादित नहीं करेंगे यदि आप कंप्यूटर से बिजली खींचते हैं, तो इसे उबलते लावा की एक शीशी में छोड़ दें, या सीपीयू को एक स्लेजहामर के साथ टुकड़ों में हरा दें। आप शायद पहले से ही जानते थे, हालांकि।

फाइनलर्स को वास्तव में अच्छी तरह से चलना चाहिए, लेकिन शटडाउन सफाई के लिए उस पर भरोसा करना सबसे अच्छा नहीं है, बल्कि चीजों को साफ-सफाई से रोकने के लिए अपने शटडाउन हुक पर भरोसा करना चाहिए। और, हमेशा की तरह, गतिरोध से सावधान रहें (मैंने देखा है कि बहुत सारे शटडाउन हुक पूरी प्रक्रिया को लटका देते हैं)!


1
दुर्भाग्य से, यह विंडोज 7 (64 बिट) पर काम नहीं करता है। मैंने बल के झंडे के बिना टास्किल का उपयोग करने की कोशिश की है, और निम्न त्रुटि का सामना करना पड़ता है: "त्रुटि: पीआईडी ​​14324 के साथ प्रक्रिया को समाप्त नहीं किया जा सकता। कारण: इस प्रक्रिया को केवल जबरदस्ती (/ एफ विकल्प के साथ) समाप्त किया जा सकता है।" बल विकल्प, "/ f" की आपूर्ति करते हुए, जाहिर है कि प्रक्रिया तुरंत बंद हो जाएगी।
जेसन हंटले

आप चलाए जा रहे फाइनल पर भरोसा नहीं कर सकते।
थोर्बोजर्न रावन एंडरसन

47

ठीक है, उन सभी संभावनाओं के बाद, जिन्हें मैंने "जावा मॉनिटरिंग एंड मैनेजमेंट" के साथ काम करने के लिए चुना
है। अवलोकन यहाँ है
जो आपको अपेक्षाकृत आसान तरीके से एक से दूसरे एप्लिकेशन को नियंत्रित करने की अनुमति देता है। आप इसे मारने से पहले नियंत्रित रूप से नियंत्रित एप्लिकेशन को रोकने के लिए स्क्रिप्ट से नियंत्रित एप्लिकेशन को कॉल कर सकते हैं।

यहाँ सरलीकृत कोड है:

नियंत्रित अनुप्रयोग:
इसे
फ़ोलोइंग VM पैरामीटर के साथ चलाएं: -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port = 9999
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management jmxremote.ssl = false

//ThreadMonitorMBean.java
public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}

// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;

public ThreadMonitor(Thread thrd)
{
    m_thrd = thrd;
}

@Override
public String getName()
{
    return "JMX Controlled App";
}

@Override
public void start()
{
    // TODO: start application here
    System.out.println("remote start called");
}

@Override
public void stop()
{
    // TODO: stop application here
    System.out.println("remote stop called");

    m_thrd.interrupt();
}

public boolean isRunning()
{
    return Thread.currentThread().isAlive();
}

public static void main(String[] args)
{
    try
    {
        System.out.println("JMX started");

        ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        ObjectName name = new ObjectName("com.example:type=ThreadMonitor");

        server.registerMBean(monitor, name);

        while(!Thread.interrupted())
        {
            // loop until interrupted
            System.out.println(".");
            try 
            {
                Thread.sleep(1000);
            } 
            catch(InterruptedException ex) 
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        // TODO: some final clean up could be here also
        System.out.println("JMX stopped");
    }
}
}

कंट्रोलिंग एप्लिकेशन:
इसे स्टॉप के साथ चलाएं या कमांड लाइन तर्क के रूप में शुरू करें

public class ThreadMonitorConsole
{

public static void main(String[] args)
{
    try
    {   
        // connecting to JMX
        System.out.println("Connect to JMX service.");
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // Construct proxy for the the MBean object
        ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
        ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);

        System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");

        // parse command line arguments
        if(args[0].equalsIgnoreCase("start"))
        {
            System.out.println("Invoke \"start\" method");
            mbeanProxy.start();
        }
        else if(args[0].equalsIgnoreCase("stop"))
        {
            System.out.println("Invoke \"stop\" method");
            mbeanProxy.stop();
        }

        // clean up and exit
        jmxc.close();
        System.out.println("Done.");    
    }
    catch(Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}


बस। :-)


7

एक और तरीका: आपका एप्लिकेशन एक सर्वर सोसाइटी खोल सकता है और उसके पास आने वाली जानकारी की प्रतीक्षा कर सकता है। उदाहरण के लिए "जादू" शब्द के साथ एक स्ट्रिंग :) और फिर शटडाउन करने के लिए प्रतिक्रिया करें: System.exit ()। आप टेलनेट जैसे बाहरी एप्लिकेशन का उपयोग करके इस तरह की जानकारी को भेज सकते हैं।


3

यहाँ थोड़ा मुश्किल है, लेकिन पोर्टेबल समाधान:

  • अपने आवेदन में शटडाउन हुक लागू करें
  • जब आप अपने जेवीएम को इनायत से बंद करना चाहते हैं, तो एक जावा एजेंट स्थापित करें जो अटैच एपीआई का उपयोग करके System.exit () कॉल करता है

मैंने जावा एजेंट को लागू किया। यह गीथब पर उपलब्ध है: https://github.com/everit-org/javaagent-shutdown

समाधान के बारे में विस्तृत विवरण यहां उपलब्ध है: https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/


2

इसी तरह का प्रश्न यहाँ

जावा में फाइनल खराब हैं। वे कचरे के संग्रह के लिए बहुत सारे ओवरहेड जोड़ते हैं। जब भी संभव हो उनसे बचें।

शटडाउन हूक को केवल तब बुलाया जाएगा जब वीएम बंद हो रहा हो। मुझे लगता है कि आप जो चाहते हैं वह बहुत अच्छा कर सकता है।


1
तो शटडाउन हूक सभी मामलों में कहा जाता है? क्या होगा अगर शेल से प्रक्रिया 'मार'?
Ma99uS

ठीक है, अगर आप इसे मार नहीं दे रहे हैं -9 :)
स्टीव जी

0

लिनक्स में सिग्नलिंग "मार" (उपलब्ध संकेतों के लिए आदमी को मारना) के साथ किया जा सकता है, आपको ऐसा करने के लिए प्रक्रिया आईडी की आवश्यकता होगी। (ps ax | grep java) या ऐसा कुछ, या प्रक्रिया के बनने पर प्रोसेस आईडी को स्टोर कर लें (यह सबसे linux स्टार्टअप फाइलों में उपयोग किया जाता है, देखें /etc/init.d)

पोर्टेबल सिग्नलिंग आपके जावा एप्लिकेशन में सॉकेटस्वर को एकीकृत करके किया जा सकता है। यह उतना मुश्किल नहीं है और आपको अपनी इच्छानुसार कोई भी आदेश भेजने की स्वतंत्रता देता है।

यदि आप अंत में फाइनल के अनुसार खंड का मतलब था; जब System.exit () को कॉल किया जाता है तो वे एक्सेस्ट नहीं होते हैं। फाइनल करने वालों को काम करना चाहिए, लेकिन वास्तव में कुछ अधिक महत्वपूर्ण नहीं करना चाहिए लेकिन एक डिबग स्टेटमेंट प्रिंट करें वे खतरनाक हैं।


0

आपके उत्तर के लिए धन्यवाद। शटडाउन कुछ इस तरह से हुक करता है जो मेरे मामले में काम करेगा। लेकिन मैं मॉनिटरिंग और मैनेजमेंट बीन्स नामक चीज़ से भी टकरा गया:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
जो दूरस्थ निगरानी और हेरफेर के लिए कुछ अच्छी संभावनाएं देता है। जावा प्रक्रिया की। (जावा 5 में पेश किया गया था)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.