How to stop java process gracefully? How to stop java process gracefully? windows windows

How to stop java process gracefully?


Shutdown hooks execute in all cases where the VM is not forcibly killed. So, if you were to issue a "standard" kill (SIGTERM from a kill command) then they will execute. Similarly, they will execute after calling System.exit(int).

However a hard kill (kill -9 or kill -SIGKILL) then they won't execute. Similarly (and obviously) they won't execute if you pull the power from the computer, drop it into a vat of boiling lava, or beat the CPU into pieces with a sledgehammer. You probably already knew that, though.

Finalizers really should run as well, but it's best not to rely on that for shutdown cleanup, but rather rely on your shutdown hooks to stop things cleanly. And, as always, be careful with deadlocks (I've seen far too many shutdown hooks hang the entire process)!


Ok, after all the possibilities I have chosen to work with "Java Monitoring and Management"
Overview is here
That allows you to control one application from another one in relatively easy way. You can call the controlling application from a script to stop controlled application gracefully before killing it.

Here is the simplified code:

Controlled application:
run it with the folowing VM parameters:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

//ThreadMonitorMBean.javapublic interface ThreadMonitorMBean{String getName();void start();void stop();boolean isRunning();}// ThreadMonitor.javapublic class ThreadMonitor implements ThreadMonitorMBean{private Thread m_thrd = null;public ThreadMonitor(Thread thrd){    m_thrd = thrd;}@Overridepublic String getName(){    return "JMX Controlled App";}@Overridepublic void start(){    // TODO: start application here    System.out.println("remote start called");}@Overridepublic 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");    }}}

Controlling application:
run it with the stop or start as the command line argument

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


That's it. :-)


An another way: your application can open a server socet and wait for an information arrived to it. For example a string with a "magic" word :) and then react to make shutdown: System.exit(). You can send such information to the socke using an external application like telnet.