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
Can You Recommend a Java Library for Reading (And Possibly Writing) CSV Files
Combineddomainxyplot Not Rescaling Domain Axis
Initial Bytes Incorrect After Java Aes/Cbc Decryption
Java Code to Convert Byte to Hexadecimal
How to Connect to Oracle Using Service Name Instead of Sid
How to Specify the Java Compiler Version in a Pom.Xml File
Why Do People Still Use Primitive Types in Java
Differencebetween Instanceof and Class.Isassignablefrom(...)
Handling Parenthesis While Converting Infix Expressions to Postfix Expressions
Resize an Array While Keeping Current Elements in Java
Java: How to Start a Standalone Application from the Current One When Both Are in the Same Package
Compiling a Java Program into an Executable
Why Use a Prime Number in Hashcode
Java: Multiple Class Declarations in One File
What's the Nearest Substitute for a Function Pointer in Java