Skip to main content

APIzation: Replication Package

[Q#2541597][A#2541618] How to gracefully handle the SIGKILL signal in Java

https://stackoverflow.com/q/2541597

How do you handle clean up when the program receives a kill signal? For instance, there is an application I connect to that wants any third party app (my app) to send a finish command when logging out. What is the best say to send that finish command when my app has been destroyed with a kill -9? edit 1: kill -9 cannot be captured. Thank you guys for correcting me. edit 2: I guess this case would be when the one calls just kill which is the same as ctrl-c

Answer

https://stackoverflow.com/a/2541618

The way to handle this for anything other than kill -9 would be to register a shutdown hook. If you can use (SIGTERM) kill -15 the shutdown hook will work. (SIGINT) kill -2 DOES cause the program to gracefully exit and run the shutdown hooks. Registers a new virtual-machine shutdown hook. The Java virtual machine shuts down in response to two kinds of events: when the exit (equivalently, System.exit) method is invoked, or interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown. I tried the following test program on OSX 10.6.3 and on kill -9 it did NOT run the shutdown hook, didn't think it would. On a kill -15 it DOES run the shutdown hook every time. There isn't any way to really gracefully handle a kill -9 in any program. In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The only real option to handle a kill -9 is to have another watcher program watch for your main program to go away or use a wrapper script. You could do with this with a shell script that polled the ps command looking for your program in the list and act accordingly when it disappeared.

APIzation

* The program exits normally, when the last non-daemon thread exits or
* The virtual machine is terminated in response to a user
public class TestShutdownHook
{
    public static void main(final String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}
#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"
package com.stackoverflow.api;

public class Human2541618 {

  public static void handleKillSignal() throws InterruptedException {
    Runtime
      .getRuntime()
      .addShutdownHook(
        new Thread() {
          @Override
          public void run() {
            System.out.println("Shutdown hook ran!");
          }
        }
      );

    while (true) {
      Thread.sleep(1000);
    }
  }
}

package com.stackoverflow.api;

/**
 * How to gracefully handle the SIGKILL signal in Java
 *
 * @author APIzator
 * @see <a href="https://stackoverflow.com/a/2541618">https://stackoverflow.com/a/2541618</a>
 */
public class APIzator2541618 {

  public static void handleSignal() throws InterruptedException {
    Runtime
      .getRuntime()
      .addShutdownHook(
        new Thread() {
          @Override
          public void run() {
            System.out.println("Shutdown hook ran!");
          }
        }
      );
    while (true) {
      Thread.sleep(1000);
    }
  }
}