start-stop-daemon and java - how to do it right? - java

I'm trying to run a java program as a service.
My requirements are:
1) start a java program on machine startup
2) restart if the java program crashes
3) execute it in a special directory as a special user
sidenotes: I CANNOT assume this being the only java process running and it would be dangerous to run the service twice by accident.
So far, I've tried implementing it with start-stop-daemon. However, the application is not automatically restarted when it crashes (i.e., terminates with a non-zero exit code). I guess it has something to do, that I need to use the --background and, thus, start-stop-daemon cannot determine the exit code? Am I correct? How do I resolve this issue properly? (I would prefer a solution with system functionality only, it would be much easier without third party tools due to security restrictions)
My current script (Dummy is, as the same says, a dummy java application which sleeps forever)
#!/bin/sh
### BEGIN INIT INFO
# Provides: CI Master
# Required-Start: $all
# Required-Stop: $all
# Should-Start: $portmap
# Should-Stop: $portmap
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: false
# Short-Description: CI Master
# Description: CI Master
### END INIT INFO
SERVICE_NAME="CI Master"
PIDFILE=/var/run/CI_master.pid
USER=ci
DIRECTORY=./master/
EXECUTABLE=/usr/bin/java
ARGUMENTS="Dummy"
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting $SERVICE_NAME" "$SERVICE_NAME"
start-stop-daemon --pidfile $PIDFILE --make-pidfile --background --chuid $USER --chdir /home/$USER/$DIRECTORY/ --startas $EXECUTABLE --start -- $ARGUMENTS
log_daemon_msg "$SERVICE_NAME started" "$SERVICE_NAME"
;;
stop)
log_daemon_msg "Stopping $SERVICE_NAME" "$SERVICE_NAME"
start-stop-daemon --pidfile $PIDFILE --remove-pidfile --stop
log_daemon_msg "$SERVICE_NAME stopped" "$SERVICE_NAME"
;;
restart|reload|force-reload)
$0 stop
sleep 1
$0 start
;;
status)
start-stop-daemon --pidfile $PIDFILE --status
case $! in
0)
log_daemon_msg "$SERVICE_NAME is running" "$SERVICE_NAME"
;;
1)
log_daemon_msg "$SERVICE_NAME is not running (pid file exists)" "$SERVICE_NAME"
;;
2)
log_daemon_msg "$SERVICE_NAME is not running" "$SERVICE_NAME"
;;
3)
log_daemon_msg "unable to determine status of $SERVICE_NAME" "$SERVICE_NAME"
;;
esac
;;
esac
exit 0
Thanks in advance!

I suggest DaemonTools + service/chkconfig.
DaemonTools maybe already installed on your platform, or you can try apt-get. It will restart your daemon automatically in at most 5 seconds.
You can look up linux user manual 8 for more information about service/chkconfig.
Hope this helpful.

I use Apache Commons Daemon Tools for this...
JSvc will respawn your Java service process for you...
Jsvc uses 3 processes: a launcher process, a controller process and a controlled process. The controlled process is also the main java thread, if the JVM crashes the controller will restart it in the next minute. Jsvc is a daemon process so it should be started as root and the -user parameter allows to downgrade to an unprivilegded user. When the -wait parameter is used, the launcher process waits until the controller says "I am ready", otherwise it returns after creating the controller process.
JSvc will write a PID File. So the -stop command can also stop your running service.
JSvc -user will allow you to demote your service to a less privileged user after startup.
It is also compatible with ProcRun.exe which works well on Windows.

I can recommend another solution - Java Service Wrapper http://wrapper.tanukisoftware.com/doc/english/introduction.html

Related

How do I launch a service on linux? [duplicate]

I have written a Java server application that runs on a standard virtual hosted Linux solution. The application runs all the time listening for socket connections and creating new handlers for them. It is a server side implementation to a client-server application.
The way I start it is by including it in the start up rc.local script of the server. However once started I do not know how to access it to stop it and if I want to install an update, so I have to restart the server in order to restart the application.
On a windows PC, for this type of application I might create a windows service and then I can stop and start it as I want. Is there anything like that on a Linux box so that if I start this application I can stop it and restart it without doing a complete restart of the server.
My application is called WebServer.exe. It is started on server startup by including it in my rc.local as such:
java -jar /var/www/vhosts/myweb.com/phpserv/WebServer.jar &
I am a bit of a noob at Linux so any example would be appreciated with any posts. However I do have SSH, and full FTP access to the box to install any updates as well as access to a Plesk panel.
I wrote another simple wrapper here:
#!/bin/sh
SERVICE_NAME=MyService
PATH_TO_JAR=/usr/local/MyProject/MyJar.jar
PID_PATH_NAME=/tmp/MyService-pid
case $1 in
start)
echo "Starting $SERVICE_NAME ..."
if [ ! -f $PID_PATH_NAME ]; then
nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
echo $! > $PID_PATH_NAME
echo "$SERVICE_NAME started ..."
else
echo "$SERVICE_NAME is already running ..."
fi
;;
stop)
if [ -f $PID_PATH_NAME ]; then
PID=$(cat $PID_PATH_NAME);
echo "$SERVICE_NAME stoping ..."
kill $PID;
echo "$SERVICE_NAME stopped ..."
rm $PID_PATH_NAME
else
echo "$SERVICE_NAME is not running ..."
fi
;;
restart)
if [ -f $PID_PATH_NAME ]; then
PID=$(cat $PID_PATH_NAME);
echo "$SERVICE_NAME stopping ...";
kill $PID;
echo "$SERVICE_NAME stopped ...";
rm $PID_PATH_NAME
echo "$SERVICE_NAME starting ..."
nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
echo $! > $PID_PATH_NAME
echo "$SERVICE_NAME started ..."
else
echo "$SERVICE_NAME is not running ..."
fi
;;
esac
You can follow a full tutorial for init.d here and for systemd (ubuntu 16+) here
If you need the output log replace the 2
nohup java -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null &
lines for
nohup java -jar $PATH_TO_JAR >> myService.out 2>&1&
A simple solution is to create a script start.sh that runs Java through nohup and then stores the PID to a file:
nohup java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt
Then your stop script stop.sh would read the PID from the file and kill the application:
PID=$(cat pid.txt)
kill $PID
Of course I've left out some details, like checking whether the process exists and removing pid.txt if you're done.
Linux service init script are stored into /etc/init.d. You can copy and customize /etc/init.d/skeleton file, and then call
service [yourservice] start|stop|restart
see http://www.ralfebert.de/blog/java/debian_daemon/. Its for Debian (so, Ubuntu as well) but fit more distribution.
Maybe not the best dev-ops solution, but good for the general use of a server for a lan party or similar.
Use screen to run your server in and then detach before logging out, this will keep the process running, you can then re-attach at any point.
Workflow:
Start a screen: screen
Start your server: java -jar minecraft-server.jar
Detach by pressing: Ctl-a, d
Re-attach: screen -r
More info here: https://www.gnu.org/software/screen/manual/screen.html
Another alternative, which is also quite popular is the Java Service Wrapper. This is also quite popular around the OSS community.
Referring to Spring Boot application as a Service as well, I would go for the systemd version, since it's the easiest, least verbose, and best integrated into modern distros (and even the not-so-modern ones like CentOS 7.x).
The easiest way is to use supervisord. Please see full details here: http://supervisord.org/
More info:
https://askubuntu.com/questions/779830/running-an-executable-jar-file-when-the-system-starts/852485#852485
https://www.digitalocean.com/community/tutorials/how-to-install-and-manage-supervisor-on-ubuntu-and-debian-vps
Here is a sample shell script (make sure you replace the MATH name with the name of the your application):
#!/bin/bash
### BEGIN INIT INFO
# Provides: MATH
# Required-Start: $java
# Required-Stop: $java
# Short-Description: Start and stop MATH service.
# Description: -
# Date-Creation: -
# Date-Last-Modification: -
# Author: -
### END INIT INFO
# Variables
PGREP=/usr/bin/pgrep
JAVA=/usr/bin/java
ZERO=0
# Start the MATH
start() {
echo "Starting MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "The service is already running"
else
#Run the jar file MATH service
$JAVA -jar /opt/MATH/MATH.jar > /dev/null 2>&1 &
#sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service was successfully started"
else
echo "Failed to start service"
fi
fi
echo
}
# Stop the MATH
stop() {
echo "Stopping MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
#Kill the pid of java with the service name
kill -9 $($PGREP -f MATH)
#Sleep time before the service verification
sleep 10
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Failed to stop service"
else
echo "Service was successfully stopped"
fi
else
echo "The service is already stopped"
fi
echo
}
# Verify the status of MATH
status() {
echo "Checking status of MATH..."
#Verify if the service is running
$PGREP -f MATH > /dev/null
VERIFIER=$?
if [ $ZERO = $VERIFIER ]
then
echo "Service is running"
else
echo "Service is stopped"
fi
echo
}
# Main logic
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart|reload)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload}"
exit 1
esac
exit 0
From Spring Boot application as a Service, I can recommend the Python-based supervisord application. See that stack overflow question for more information. It's really straightforward to set up.
Other answers do a good job giving custom scripts and setups depending on your platform. In addition to those, here are the mature, special purpose programs that I know of:
JSW from TanukiSoftware
YAJSW is an open source clone from the above. It is written in Java, and it is a nanny process that manages the child process (your code) according to configurations. Works on windows / linux.
JSVC is a native application. Its also a nanny process, but it invokes your child application through the JNI, rather than as a subprocess.
You can use Thrift server or JMX to communicate with your Java service.
From Spring Boot Reference Guide
Installation as an init.d service (System V)
Simply symlink the jar to init.d to support the standard start, stop, restart and status commands.
Assuming that you have a Spring Boot application installed in /var/myapp, to install a Spring Boot application as an init.d service simply create a symlink:
$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
Once installed, you can start and stop the service in the usual way. For example, on a Debian based system:
$ service myapp start
If your application fails to start, check the log file written to /var/log/<appname>.log for errors.
Continue reading to know how to secure a deployed service.
After doing as written I've discovered that my service fails to start with this error message in logs: start-stop-daemon: unrecognized option --no-close. And I've managed to fix it by creating a config file /var/myapp/myapp.conf with the following content
USE_START_STOP_DAEMON=false
It is possible to run the war as a Linux service, and you may want to force in your pom.xml file before packaging, as some distros may not recognize in auto mode. To do it, add the following property inside of spring-boot-maven-plugin plugin.
<embeddedLaunchScriptProperties>
<mode>service</mode>
</embeddedLaunchScriptProperties>
Next, setup your init.d with:
ln -s myapp.war /etc/init.d/myapp
and you will be able to run
service myapp start|stop|restart
There are many other options that you can find in Spring Boot documentation, including Windows service.
Im having Netty java application and I want to run it as a service with systemd. Unfortunately application stops no matter of what Type I'm using. At the end I've wrapped java start in screen. Here are the config files:
service
[Unit]
Description=Netty service
After=network.target
[Service]
User=user
Type=forking
WorkingDirectory=/home/user/app
ExecStart=/home/user/app/start.sh
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
start
#!/bin/sh
/usr/bin/screen -L -dmS netty_app java -cp app.jar classPath
from that point you can use systemctl [start|stop|status] service.
To run Java code as daemon (service) you can write JNI based stub.
http://jnicookbook.owsiak.org/recipe-no-022/
for a sample code that is based on JNI. In this case you daemonize the code that was started as Java and main loop is executed in C. But it is also possible to put main, daemon's, service loop inside Java.
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo029
Have fun with JNI!
However once started I don't know how to access it to stop it
You can write a simple stop script that greps for your java process, extracts the PID and calls kill on it. It's not fancy, but it's straight forward.
Something like that may be of help as a start:
#!/bin/bash
PID = ps ax | grep "name of your app" | cut -d ' ' -f 1
kill $PID

How do I run Java as a service on Ubuntu?

So after 2 days (yes I'm a complete rookie when it comes to servers) trying to get this working I give up and turn to SO for help :)
I want to start my java app on start, log to a logfile. That's it :)
start on runlevel [2345]
stop on runlevel [!2345]
#Respawn the process if it crashes
#If it respawns more than 10 times in 5 seconds stop
respawn
respawn limit 10 5
expect fork
script
cd /home/ubuntu/admin/
mvn spring-boot:run > /var/log/upstart/admin.log 2>&1
end script
Running "sudo start admin" works and I get "admin start/running" in console.. No log is created and the java app is not started.. ?
What am I missing?
How do I run Java as a service on Ubuntu?
I don't mean to sidetrack, but I've deployed Java applications on Ubuntu in production since 2010 and had very little success with Upstart. I use init.d scripts and start-stop-daemon. Side bonus: it works on more distros.
Create /etc/init.d/my-java-app:
#!/bin/sh
#
# my-java-app My Java App
#
# chkconfig: - 80 05
# description: Enable My Java Application
#
### BEGIN INIT INFO
# Provides: my-java-app
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: My Java Application
# Short-Description: Enable My Java Application
### END INIT INFO
DESC="my java app"
NAME=my-java-app
PIDFILE=/var/run/$NAME.pid
RUN_AS=ubuntu
WORK_DIR=/home/ubuntu/admin
DAEMON=/usr/bin/mvn
DAEMON_OPTS="spring-boot:run"
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
do_start() {
start-stop-daemon --start --quiet --make-pidfile --pidfile $PIDFILE \
--background \
--chuid $RUN_AS \
--chdir $WORK_DIR \
--exec $DAEMON -- $DAEMON_OPTS
}
do_stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE
if [ -e $PIDFILE ]
then rm $PIDFILE
fi
}
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
do_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
do_stop
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
do_stop
sleep 1
do_start
echo "."
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "usage: $NAME {start|stop|restart}"
exit 1
;;
esac
Make it belong to root, make it executable, and set it up to run on startup with:
sudo chown root:root /etc/init.d/my-java-app
sudo chmod 755 /etc/init.d/my-java-app
sudo update-rc.d my-java-app defaults
To start the service you can run:
sudo service my-java-app start
To stop the service you can run:
sudo service my-java-app stop
This is based on a simplified version of the /etc/init.d/skeleton file included by Ubuntu.
The man page for start-stop-daemon is worth looking at if you want to tweak this further.b

How to start Apache Solr automatically? [duplicate]

At the moment I have to go to /usr/java/apache-solr-1.4.0/example and then do:
java -jar start.jar
How do I get this to start automatically on boot?
I'm on a shared Linux server.
As you're on a shared Linux box, you'll have to ask the system administrator to do the following, probably.
Create a startup script in /etc/init.d/solr.
Copy this code, my Solr startup script, into that file:
#!/bin/sh
# Prerequisites:
# 1. Solr needs to be installed at /usr/local/solr/example
# 2. daemon needs to be installed
# 3. Script needs to be executed by root
# This script will launch Solr in a mode that will automatically respawn if it
# crashes. Output will be sent to /var/log/solr/solr.log. A PID file will be
# created in the standard location.
start () {
echo -n "Starting solr..."
# Start daemon
daemon --chdir='/usr/local/solr/example' --command "java -jar start.jar" --respawn --output=/var/log/solr/solr.log --name=solr --verbose
RETVAL=$?
if [ $RETVAL = 0 ]
then
echo "done."
else
echo "failed. See error code for more information."
fi
return $RETVAL
}
stop () {
# Stop daemon
echo -n "Stopping solr..."
daemon --stop --name=solr --verbose
RETVAL=$?
if [ $RETVAL = 0 ]
then
echo "Done."
else
echo "Failed. See error code for more information."
fi
return $RETVAL
}
restart () {
daemon --restart --name=solr --verbose
}
status () {
# Report on the status of the daemon
daemon --running --verbose --name=solr
return $?
}
case "$1" in
start)
start
;;
status)
status
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: solr {start|status|stop|restart}"
exit 3
;;
esac
exit $RETVAL
Then run:
chkconfig --add solr
Or (on Ubuntu):
update-rc.d solr defaults
... or, if your Linux distribution doesn't have chkconfig (or update-rc.d), link /etc/init.d/solr to /etc/rc3.d/S99solr and /etc/rc5.d/S99solr and /etc/rc3.d/K01solr and /etc/rc5.d/K01solr:
% ln -s /etc/init.d/solr /etc/rc3.d/S99solr
% ln -s /etc/init.d/solr /etc/rc5.d/S99solr
% ln -s /etc/init.d/solr /etc/rc3.d/K01solr
% ln -s /etc/init.d/solr /etc/rc5.d/K01solr
Now on reboot Solr will startup in run levels 3 and 5 (console with network & full GUI).
To start solr manually run:
% /etc/init.d/solr start
If you have root access to your machine, there are a number of ways to do this based on your system's initialization flow (init scripts, systemd, etc.)
But if you don't have root, cron has a clean and consistent way to execute programs upon reboot.
First, find out where java is located on your machine. The command below will tell you where it is:
$ which java
Then, stick the following code into a shell script, replacing the java path below (/usr/bin) with the path you got from the above command.
#!/bin/bash
cd /usr/java/apache-solr-1.4.0/example
/usr/bin/java -jar start.jar
You can save this script in some location (e.g., $HOME) as start.sh. Give it world execute permission (to simplify) by running the following command:
$ chmod og+x start.sh
Now, test the script and ensure that it works correctly from the command line.
$ ./start.sh
If all works well, you need to add it to one of your machine's startup scripts. The simplest way to do this is to add the following line to the end of /etc/rc.local.
# ... snip contents of rc.local ...
# Start Solr upon boot.
/home/somedir/start.sh
Alternatively, if you don't have permission to edit rc.local, then you can add it to your user crontab as so. First type the following on the commandline:
$ crontab -e
This will bring up an editor. Add the following line to it:
#reboot /home/somedir/start.sh
If your Linux system supports it (which it usually does), this will ensure that your script is run upon startup.
If I don't have any typos above, it should work out well for you. Let me know how it goes.
Adding the following lines to my /etc/init.d/solr file works to support Red Hat Linux (I copied them from /etc/init.d/mysql after reading comments by others here).
# Comments to support chkconfig on Red Hat Linux
# chkconfig: 2345 64 36
# Description: A very fast and reliable search engine.
There are three steps that you need to do here:
Create the script, make it executable, and put it in the right place.
Make the script start up properly on reboot.
Bonus: Set up a logrotation script so logs don't get out of control.
For number one, I've tuned supermagic's script from above. It was OK, but had a number of typos, lacked some functionality (status, restart), didn't use the daemon utility very effectively.
Here's my version of the script (make sure you have daemon installed for it to work):
#!/bin/sh
# Prerequisites:
# 1. Solr needs to be installed at /usr/local/solr/example
# 2. daemon needs to be installed
# 3. Script needs to be executed by root
# This script will launch Solr in a mode that will automatically respawn if it
# crashes. Output will be sent to /var/log/solr/solr.log. A pid file will be
# created in the standard location.
start () {
echo -n "Starting solr..."
# start daemon
daemon --chdir='/usr/local/solr/example' --command "java -jar start.jar" --respawn --output=/var/log/solr/solr.log --name=solr --verbose
RETVAL=$?
if [ $RETVAL = 0 ]
then
echo "done."
else
echo "failed. See error code for more information."
fi
return $RETVAL
}
stop () {
# stop daemon
echo -n "Stopping solr..."
daemon --stop --name=solr --verbose
RETVAL=$?
if [ $RETVAL = 0 ]
then
echo "done."
else
echo "failed. See error code for more information."
fi
return $RETVAL
}
restart () {
daemon --restart --name=solr --verbose
}
status () {
# report on the status of the daemon
daemon --running --verbose --name=solr
return $?
}
case "$1" in
start)
start
;;
status)
status
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: solr {start|status|stop|restart}"
exit 3
;;
esac
exit $RETVAL
Place this script at /etc/init.d/solr, make it executable, and you should be good with step one. You can now start/stop/restart/status a solr daemon with /etc/init.d/solr start|stop|restart|status
For step two, run the following on an Ubuntu machine (don't know about Redhat):
update-rc.d solr defaults
Once this is done, you're in pretty good shape, but you probably want to rotate the logs properly at some point, so here's a good config for the logs:
/var/log/solr/*.log {
weekly
rotate 12
compress
delaycompress
create 640 root root
postrotate
/etc/init.d/solr restart
endscript
}
Place that file in /etc/logrotate.d/solr, and you should be good to go, assuming logrotate is running (it usually is).
I answered this question once already, but that answer was for operating systems that used SysV and this one is for newer operating systems that are increasingly using systemd.
As in my other answer, there are three things you'll need to do here:
Create the script and put it in the right place.
Make the script start up properly on reboot.
Bonus: Make systemd logs persistent.
1. Creating the script and putting it in the right place
Here's a systemd unit file that you can use (these replace the SysV init files). Name it solr.service.
[Unit]
Description=Apache Solr
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
Environment="XMX=2G"
WorkingDirectory=/usr/local/solr/example
ExecStart=/usr/bin/java -jar -server -Xmx${XMX} start.jar
Restart=on-failure
LimitNOFILE=10000
[Install]
WantedBy=multi-user.target
Note that there's a configuration in there for Solr's memory. You'll probably want to tweak that to your own purposes. If you have a number of variables you're passing to systemd, you can do that with the EnvironmentFile directive.
More documentation for these files is here.
2. Make the script startup properly at boot
This is fairly simple, but there are rules. To make it start at boot, put the file in /etc/systemd/system/solr.service. You cannot use a symlink in this directory, do not try.
Once that's in there, you can enable the daemon to run at boot with:
sudo systemctl enable solr
And you can start, stop, status it with:
sudo systemctl {start|stop|status} solr
3. Making systemd logs persistent
By default, systemd logs are not persistent and they are lost whenever you reboot the system. If that's not what you desire, you can make them persistent by creating a directory:
sudo mkdir -p /var/log/journal/
And then restarting the systemd journaling daemon:
sudo systemctl restart systemd-journald
Once that's complete, systemd's journaling daemon will receive all the stdout and stderr that Solr creates and it will get stored in a binary format under /var/log/journal/.
The way systemd handles logging is pretty neat and is worth studying if you're not familiar with it. In the meantime, just know that to read your log entries you'll need to use a new tool called journalctl. For example, this will follow your solr logs:
journalctl -u solr -f
And there are also flags for doing date-based filtering and things like that.
3.1 Tweaking the log files
Bonus section! If you want to tweak the log files, you can read all about it in the documentation here, but the defaults are actually very safe and sane (logs are compressed by default, can't grow too large, are rate limited, and are written to disk in batches).
Follow supermagic's comments, then follow this
http://codingrecipes.com/service-x-does-not-support-chkconfig
He says,
1 – Copy your script into /etc/init.d folder
2 – cd /etc/init.d
3 – chmod +x myscript
4 – Add these lines, including #, right after #!/bin/bash or #!/bin/sh:
# chkconfig: 2345 95 20
# description: Some description
# What your script does (not sure if this is necessary though)
# processname: myscript
Then you can do
chkconfig --add myscript
init.d/solr script that's tested on Centos 6/Amazon Linux. It wraps solr's native CLI.
#!/bin/bash
# description: Starts and stops Solr production
PIDFILE=/var/run/solr.pid
SOLR_HOME=/usr/share/solr
START_COMMAND="$SOLR_HOME/bin/solr start -p 8984 -noprompt -m 1g"
NAME="Solr"
start() {
echo "Starting $NAME"
if [ -f $PIDFILE ]; then
echo -n "$PIDFILE exists. $NAME may be running."
else
str=`$START_COMMAND`
pid=`echo $str | grep -o "pid=[0-9]*" | grep -o "[0-9]*"`
if [ "$pid" == "" ];
then
echo "[FATAL ERROR] Failed to extract pid. Exiting!"
exit 1
fi
echo $pid > $PIDFILE
fi
return 0
}
case "$1" in
start)
start
;;
stop)
echo "Stopping $NAME .."
$SOLR_HOME/bin/solr stop
rm -f $PIDFILE
;;
status)
$SOLR_HOME/bin/solr status
;;
restart)
$0 stop
#sleep 2
$0 start
;;
*)
echo "Usage: $0 (start | stop | restart | status)"
exit 1
;;
esac
exit $?
Check
man 5 crontab
See if #reboot is supported on the Linux system you are using.

Java "java.util.logging.Logger" does not work when running with nohup

I created a Java application which is supposed to run as an ubuntu service. I followed this article: Running a Java program as a daemon in Ubuntu Linux
This is my script in /etc/init.d/ dir:
#!/bin/sh
### BEGIN INIT INFO
# Provides: myservice
# 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 myservice
### END INIT INFO
case $1 in
status)
if [ -f /opt/myservice/pid ]; then
PID=$(cat /opt/myservice/pid);
echo "myservice is running. PID="$PID
else
echo "myservice is not running."
fi
;;
start)
if [ ! -f /opt/myservice/pid ]; then
nohup java -jar /opt/myservice/billing_consumer.jar /opt/myservice 2>> /dev/null >> /dev/null &
echo $! > /opt/myservice/pid
echo "myservice started ..."
else
echo "myservice is already running ..."
fi
;;
stop)
if [ -f /opt/myservice/pid ]; then
PID=$(cat /opt/myservice/pid);
kill $PID;
echo "myservice stopped ..."
rm /opt/myservice/pid
else
echo "myservice is not running ..."
fi
;;
restart)
if [ -f /opt/myservice/pid ]; then
PID=$(cat /opt/myservice/pid);
echo "Stopping myservice ...";
kill $PID;
echo "myservice stopped ...";
rm /opt/myservice/pid
echo "Starting myservice ..."
nohup java -jar /opt/myservice/billing_consumer.jar /opt/myservice 2>> /dev/null >> /dev/null &
echo $! > /opt/myservice/pid
echo "myservice started ..."
else
echo "myservice is not running ..."
fi
;;
esac
It seems that this script closes the billing_consumer.jar standard input and redirects output to /dev/null; which, I read somewhere that it's the bitbucket which is used for redirecting console's output to that in this place. Also I don't have anything to be sent to stderr or stdout except some third party components which use those outputs. I myself use java's builting logging API (java.util.logging.Logger) to log information. I use the java.util.logging.FileHandler as the handler for logging outputs. But the problem is that, when I run the program as a service logging does not work. But when I run the program manually, I can see the logs written in the files. This is my logging.properties file used for logging configuration:
handlers = java.util.logging.FileHandler
config =
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.filter =
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.encoding =
java.util.logging.FileHandler.limit = 1048576
java.util.logging.FileHandler.count = 20
java.util.logging.FileHandler.append = true
java.util.logging.FileHandler.pattern = logs/billing-log.%u.%g.log
...
I don't think this has anything to do with the /etc/init.d/myservice script, Since I changed that to redirect the output to a file also and I could see that the third party components' outputs are written in the file. Although, I am not writing to terminals' output. Can anyone figure out what is the problem here. Do I have configured logging the wrong way?
In your logging properties you are using a relative path. When you run this as a service the current/working directory is probably different from when you run this manually. The FileHandler will fail to create a new log file if the directory path doesn't exist. Set the working directory or change the path to an absolute path.
The 'config =' line looks wrong since there is no value.
If that doesn't work you should modify the script to pipe the out/err streams to a file to debug what is going on.

JSVC Cannot Register Native Methods

I'm trying to create a service that will run in Ubuntu Linux written in Java. My executable Jar file is a big fat Jar file that has all the dependencies packaged inside with it. I get the following error when I try to run it using JSVC.
Java VM created successfully
Class org/apache/commons/daemon/support/DaemonLoader found
Cannot register native methods
java_init failed
Service exit with a return value of 1
What's killing me is the "cannot register native methods" line. What does this mean and how do I fix it?
I'm writing my app in Java using the Eclipse IDE, I installed the latest version of JSVC using apt-get (1.0.10-3). My commons.daemon library version is 1.0.1. My startup script is below.
#!/bin/sh
# Setup variables
EXEC=jsvc
JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-amd64
CLASS_PATH="/usr/hadoop-1.1.1/lib/commons-daemon-1.0.1.jar":"/usr/devel/Hadoop_LCS/"
CLASS=com.foo.hadoop.lcs.Program
USER=hduser
PID=/tmp/lcs_process.pid
LOG_OUT=/tmp/lcs_log.out
LOG_ERR=/tmp/lcs_log.err
do_exec()
{
$EXEC -home "$JAVA_HOME" -cp $CLASS_PATH -user $USER -debug -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS
}
case "$1" in
start)
do_exec
;;
stop)
do_exec "-stop"
;;
restart)
if [ -f "$PID" ]; then
do_exec "-stop"
do_exec
else
echo "Service not running, will do nothing"
exit 1
fi
;;
*)
echo "usage: daemon {start|stop|restart}" >&2
exit 3
;;
esac
I got it. I just upgraded my version of the Apache commons.daemon library and that did the trick. I got 1.0.15.

Categories

Resources