Capture SIGINT in Java
Solution 1:
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.
Solution 2:
Since at least Java 6, the HotSpot java
command has had a -Xrs
flag to disable the JVM signal handlers.
If you use it, you need to implement your own SIGINT
, SIGTERM
, SIGHUP
, and SIGQUIT
handlers, including one to explicitly call System.exit()
.
Note: this means the thread dump facility of SIGQUIT is disabled when the -Xrs
flag is present.
See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI (also available on the Windows and Solaris java
counterparts).
Solution 3:
Take a look at Integrating Signal and Exception Handling describing the HotSpot JVM's ability do do signal chaining. It does involve some C-level trickery though.
Wouldn't java.lang.Runtime.addShutdownHook(Thread)
be enough for your purpose? These hooks are run by the JVM upon termination, including reception of SIGINT
, as long as the JVM is able to perform them.