In Linux you can give the following commands:
service <someService> start
service <someService> stop
As opposed to killing the process with kill -9 <someService>
. As I learned in an earlier question, this is the difference between sending the process a SIGTERM
(former) and a SIGKILL
(latter).
So how does one go about "registering" (and coding) an ordinary JAR or WAR as a service/daemon that can be started and stopped with those commands? I would imagine that Java must have some API for handling SIGTERM
s?
Thanks in advance!
If you just want to run some shutdown specific code, the "proper Java" way to handle this would not use signals, but would instead add a generic "shutdown hook" that would run when your application was about to terminate. This is one of those least-common-denominator problems that Java sometimes suffers from. (Since not all platforms support SIGINT
, in Java, no platform supports SIGINT
.)
Unfortunately, you don't get much context in a ShutdownHook
, but it may still be useful:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run()
{
// cleanup
}
}));
If you really need to distinguish between the signal received, or you want to support signals that Java normally ignores (like USR1
), or you want to abort shutdown based on a signal, then a ShutdownHook
will be mostly useless for you, unfortunately.
There is a non-supported, poorly-documented way to capture signals in the Sun JVM, using the sun.misc.SignalHandler
class. This is questionably portable, though it appears that the IBM JVM also supports this.
For example - you could hook up a signal handler to listen to SIGHUP
reload your server configuration, which was set up in the init.d
script as the reload
verb:
Signal.handle(new Signal("HUP"), new SignalHandler() {
public void handle(Signal signal)
{
reloadConfiguration();
}
});
As for configuring a Java application to be controlled using the system
command, you should write a shell script in init.d
program that starts it up. This simply needs to respond to the start
and stop
verbs and take the appopriate action. For example, this could be your /etc/init.d/my-java-program
:
#!/bin/sh
case "$1" in
start)
java /path/to/my/java/program.jar &
echo $! > /var/run/my-java-program.pid
;;
stop)
if [ ! -f /var/run/my-java-program.pid ]; then
echo "my-java-program: not running"
exit 1
fi
kill -TERM `cat /var/run/my-java-program.pid`
;;
reload)
if [ ! -f /var/run/my-java-program.pid ]; then
echo "my-java-program: not running"
exit 1
fi
kill -HUP `cat /var/run/my-java-program.pid`
;;
*)
echo "Usage: /etc/init.d/my-java-program {start|stop|reload}"
exit 1
;;
esac
exit 0
You can now start your application by running /etc/init.d/my-java-program start
, or on CentOS, you can also use service my-java-program start`.