How to run a Java Program as a daemon (Background service) on *nix systems?
Ever needed to run a Java program as a daemon (background service) on your *nix server? All you want is to run some basic operations such as start/stop/restart? then are not a lone.
If you google around for sometime, you will be able to find one or more of the following options:
- Java Service Wrapper.
- Apache Jakarta Commons Daemon package (Jsvc).
- Write your own custom shell script.
The first two options are much more advanced and you can do a lot more by using them. However, they come with some complexities such as compatibility issues, having the need to implement custom interfaces, or that it requires installation of some extra packages before using. A shell script, on the other hand, is easier to adapt to changing OS and Java environments.
So I decided to spend sometime to write a shell script that can be use as template for managing any java program. So I came up with SJSWS (Simple Java Service Wrapper Script).
Basically, SJSWS is a simple tool to generate a custom shell script to manage any java program as a service (Start/Stop/restart/etc…). For the full details about the tool and how generate your own, you follow the example described in the SJSWS git repo.
For now the tool simply reads pre-configured values from a property file (Service.properties) and inject them into template (ServiceTemplate.sh) to generate script customized to run a specific service.
However, since the tool is doing some basic tasks for now (read values and feed them into a template file ), you have the options to manually do that. Here what the ServiceTemplate.shlooks like today:
#!/bin/sh
### BEGIN INIT INFO
# Provides: V_SERVICE_NAME
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: Start/stop/restart/etc.. service wrapper to run java program as deamon.
### END INIT INFO
# author: Suleiman Alrosan
# version: v0.1
SERVICE_NAME=V_SERVICE_NAME
SERVICE_WORK_DIR=V_SERVICE_WORK_DIR
SERVICE_PID_FILE=V_SERVICE_PID_FILE
SERVICE_CLASS_PATH=V_SERVICE_CLASS_PATH
SERVICE_CLASS=V_SERVICE_CLASS
SERVICE_CMD=V_SERVICE_CMD
get_conf()
{
echo "
--------------------------------------- \033[7mService Configuration\033[0m ---------------------------------------
The following list represent the service configurations:
-\033[1mSERVICE_NAME\033[0m: $SERVICE_NAME
-\033[1mSERVICE_WORK_DIR\033[0m: $SERVICE_WORK_DIR
-\033[1mSERVICE_PID_FILE\033[0m: $SERVICE_PID_FILE
-\033[1mSERVICE_CLASS_PATH\033[0m: $SERVICE_CLASS_PATH
-\033[1mSERVICE_CLASS\033[0m: $SERVICE_CLASS
-\033[1mSERVICE_CMD\033[0m: $SERVICE_CMD
------------------------------------------------------------------------------------------------------------
"
}
do_start()
{
echo "Starting $SERVICE_NAME service ..."
#nohup java -cp $SERVICE_CLASS_PATH $SERVICE_CLASS $SERVICE_WORK_DIR 2>> /dev/null >> /dev/null &
nohup $SERVICE_CMD $SERVICE_WORK_DIR 2>> /dev/null >> /dev/null &
echo $! > $SERVICE_PID_FILE
PID=$(cat $SERVICE_PID_FILE);
echo "$SERVICE_NAME service started with PID[$PID]..."
}
do_stop()
{
PID=$(cat $SERVICE_PID_FILE);
echo "Stopping $SERVICE_NAME service with PID[$PID]..."
kill $PID;
echo "$SERVICE_NAME stopped ..."
rm $SERVICE_PID_FILE
}
do_restart()
{
do_stop
do_start
}
get_status()
{
if [ ! -f $SERVICE_PID_FILE ]; then
echo "$SERVICE_NAME service is not running"
else
PID=$(cat $SERVICE_PID_FILE);
echo "$SERVICE_NAME service is running on PID[$PID]"
fi
}
get_pid(){
if [ ! -f $SERVICE_PID_FILE ]; then
echo "NO ACTIVE PID"
else
PID=$(cat $SERVICE_PID_FILE);
echo "PID: $PID"
fi
}
print_help()
{
echo '
-------------------------- \033[7mSimple Java Service Wrapper Script(SJSWS)\033[0m -----------------------------
This is a simple script to manage java programs(Start/stop/restart/etc.. ), which can be setup as deamon(background service).
The script accepts the following commands:
- \033[1mh,help\033[0m: print information about the scrip.
- \033[1mconf\033[0m: print the current configuration values for the service.
- \033[1mst, status\033[0m: print the current status of the service.
- \033[1mstart\033[0m: start the service by executing the configured java command.
- \033[1mstop\033[0m: stop the service by killing the PID.
- \033[1mrestart\033[0m: restart the configured service by stopping and then starting the service again.
- \033[1mpid\033[0m: print the PID for service.
'
}
case $1 in
h)
print_help
;;
help)
print_help
;;
pid)
get_pid
;;
conf)
get_conf
;;
st)
get_status
;;
status)
get_status
;;
start)
if [ ! -f $SERVICE_PID_FILE ]; then
do_start
else
echo "$SERVICE_NAME service is already running."
fi
;;
stop)
if [ -f $SERVICE_PID_FILE ]; then
do_stop
else
echo "$SERVICE_NAME service is already stopped."
fi
;;
restart)
if [ -f $SERVICE_PID_FILE ]; then
do_restart
else
echo "$SERVICE_NAME service is not running. Start the service first."
fi
;;
*)
echo "Invalid command. See help for more information."
;;
esac
All you need to do is to replace the values that start with “V_”, with values that is specific to your program. Here is the description for each variable:
Property Name | Description |
---|---|
SERVICE_NAME | The name of your service without any spaces |
SERVICE_WORK_DIR | The location to the dir where your jar file is located. |
SERVICE_PID_FILE | File name with full path that the service will use to store the process ID. The default is $SERVICE_WORK_DIR"/"$SERVICE_NAME"_pid" |
SERVICE_CLASS_PATH | Path to your jars |
SERVICE_CLASS | Full class name that has the main method for your java program |
SERVICE_CMD | The actual command that the final script will execute to start your service. Default is “java -cp $SERVICE_CLASS_PATH $SERVICE_CLASS” |
Once you have your script ready, all you need to do is set it up as service. This step might be different from Linux system to another. Here is how it works Ubuntu 14.04.3 LTS :
# sudo cp output/service.sh /etc/init.d/myJavaService
# sudo chmod +x /etc/init.d/myJavaService
# sudo update-rc.d myJavaService defaults
That’s it!!! Now you have myJavaService setup as a daemon. You can start, stop, get the status and PID for your service :
# /etc/init.d/myJavaService start
# /etc/init.d/myJavaService st
# /etc/init.d/myJavaService pid
# /etc/init.d/myJavaService restart
# /etc/init.d/myJavaService stop
# /etc/init.d/myJavaService conf
# /etc/init.d/myJavaService help
great
ReplyDelete