Java Daemon
More than once I needed to start a Java program in a daemon mode.
I am aware of the existence of the packages like Apache Commons Daemon and Tanuki Service Wrapper. I never understood what benefits they have over native-libraries-free pure-Java solutions (at least, in simple cases and not on Windows :)). Yes, it is somewhat tricky to record a pid in a pid file and such, by I prefer not to use native libraries - unless I have to.
Recently, I had to do this again. It turned out that FuseJ - Java-to-Fuse binding - is broken in background mode, so I had to improvise… But the reason is less important than the result :)
My colleague Dima pointed me towards a 2005 article by Peter Williams on the subject. And it turned out to be such a very thorough and thought-through article, that I just wanted to record it here ;)
One of the techniques mentioned in the article is: close standard input of a program being daemonized (<&-
on the
command line) and start it in the background (&
at the end of the command line); then close standard output and error
from within it. I understand why he does not want to close all standard file descriptors: he wants to be able to log to
console during the startup sequence. I did not understand why does he bother closing the standard input from the command
line - and not from within the process?
I am starting to understand that, I think. I tried a simplified approach - just &
on the command line; close
everything from within the process. It works fine on Fedora 14 under bash: shell prints the pid of the backgrounded
process and continues; the process logs to console and to log file, then closes everything and runs as a daemon. On
CentOs under tcsh the results are very different: the shell prints the pid, but after I press <enter>
, the shell prints
“Suspended (tty output)”; nothing gets logged to console; only the first line gets logged to the log file; the process
is not running.
I suspect that the process is wedged because standard input is still open when the process is backgrounded. Since tcsh
understood the same close-the-standard-input unprintable (<&-
) that bash does, I use non-bash-specific way to detach
standard input from the keyboard on the command line: < /dev/null
.