How to Gracefully Handle the Sigkill Signal in Java

How to gracefully handle the SIGKILL signal in Java

It is impossible for any program, in any language, to handle a SIGKILL. This is so it is always possible to terminate a program, even if the program is buggy or malicious. But SIGKILL is not the only means for terminating a program. The other is to use a SIGTERM. Programs can handle that signal. The program should handle the signal by doing a controlled, but rapid, shutdown. When a computer shuts down, the final stage of the shutdown process sends every remaining process a SIGTERM, gives those processes a few seconds grace, then sends them a SIGKILL.

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:

  • The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
  • The virtual machine is terminated in response to a user 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, as expected. On a kill -15 it DOES run the shutdown hook every time.

public class TestShutdownHook
{
public static void main(String[] args) throws InterruptedException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
System.out.println("Shutdown hook ran!");
}
});

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

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.

#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"

How to process SIGTERM signal gracefully in Java?

I rewritten the registerShutdownHook() method and now it works as I wanted.

private static void registerShutdownHook() {
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
System.out.println("Tralala");
Hellow.setShutdownProcess();
mainThread.join();
} catch (InterruptedException ex) {
System.out.println(ex);
}

}
});
}

Capture SIGINT in Java

The way to handle this would be to register a shutdown hook. If you use (SIGINT) kill -2 will 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:

  • The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or

  • The virtual machine is terminated in response to a user 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.

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

This is the documented way to write your own signal handlers that aren't shutdown hooks in Java. Be warned that the com.sun.misc packages and are un-supported and may be changed or go away at any time and probably only exist in the Sun JVM.

How to exit gracefully a java application?

Register a shutdown hook with the Java Runtime. The shutdown of JVM will be notified on the registered thread. Below is an example:

public class Main {

public static void main(String[] args) {

Runtime.getRuntime().addShutdownHook(new ShutDownHookThread());

while (true) {

}

}

}

class ShutDownHookThread extends Thread {
@Override
public void run() {
// ***write your code here to handle any shutdown request
System.out.println("Shut Down Hook Called");
super.run();
}
}

SIGKILL signal Handler

You cannot, at least not for the process being killed.

What you can do is arrange for the parent process to watch for the child process's death, and act accordingly. Any decent process supervision system, such as daemontools, has such a facility built in.

Issue with Java Shutdown hook

You can't handle that case. It seems Eclipse is sending a SIGKILL which is not part of a graceful shutdown, and thereby cannot be caught. See https://stackoverflow.com/a/2541618/3560873

Graceful termination of a Java program and logging of terminate signals

Is this a good way to implement graceful termination?

You aren't doing much, so graceful doesn't really mean anything. Shutdown hooks really are the only way to handle these signals.

How can I print out the caught signal?

You can't. The signal is caught at the JVM level. It'll run System#exit(int) (or rather Shutdown#exit(int)). The JVM does not provide any extra information you can use.



Related Topics



Leave a reply



Submit