Java Daemon

Lately I have been writing a Java program that needs to run in the back ground (like a daemon). I found a couple of neat little tricks that can make this easier. These ideas probably only work in a Unix environment but they have been tested on Linux and Solaris.

So you have your program and you want to start it such that it will not be killed when you log out of the shell in which you start it. You could use nohup, but nohup redirects the standard out and error to files, which is annoying because you are writing all output to a log file anyway. You could do java -cp your_class_path com.domain.main_class <&- 1>/dev/null 2>&1 & which runs the program in the background, closes standard in, and redirects standard out and error to the bit bucket. By closing standard in to the process the shell will not kill the program when it exits and it is running in the background so it will not interfere with other actions we might want to perform with this shell.

However, it would be nice if you could print errors that occur during startup to the prompt — for example if the config file were missing. This is nice because it is generally appropriate to sanity check the configuration so that if the program starts there is a significant chance it will actually work correctly. So let’s not redirect standard out and error. That leaves you with
java -cp your_class_path com.domain.main_class <&- &, which works but a shell will not exit while there are still programs attached to its standard out and error — as this one is.

The solution is to have the Java program detach from standard out and error once its startup is complete. So we will create a method called daemonize() that we will call just before entering the infinite loop that is the main program logic.

static public void daemonize()
{
   System.out.close();
   System.err.close();
}

So now we have a main method which looks like

static public void main(String[] args)
{
   try
   {
       // do sanity checks and startup actions
       daemonize();
   }
   catch (Throwable e)
   {
       System.err.println("Startup failed.");
       e.printStackTrace();
   }

   // do infinite loop
}

Now when we start our program we get to see if it started correctly and if it does start it will not be killed when the shell exits nor will it prevent the shell from exiting.

Now that the program is completely detached from the shell the only way to stop it is by killing the process. However, to do that you need to know the pid. Java has no way for a program to figure its pid directly — it is too system dependent. So we will create a shell script to launch our daemon and record its pid for future use.

#!/bin/sh
java -cp your_class_path com.domain.main_class &lt;&amp;- &
pid=$!
echo ${pid} > mydaemon.pid

This script launches the program and then writes the pid to the file ‘mydaemon.pid’. Now when you want to kill the program you can do

kill `cat mydaemon.pid`

There are a couple of problems with this, one is that the pid file gets written even if the daemon failed to start successfully, another is that if the daemon crashes the pid file will still exist — which might lead you to believe it is still working.

We can solve the pid file surviving daemon crash problem by passing it into the Java program like the following

java -Ddaemon.pidfile=mydaemon.pid -cp your_class_path com.domain.main_class &lt;&amp;- &

And the updated the daemonize() method to the following

.

static public void daemonize()
{
   getPidFile().deleteOnExit();
   System.out.close();
   System.err.close();
}

where getPidFile() is a method which returns a File object file specified by the system property “daemon.pidfile”. That way the pid file will be deleted when the VM exits.

For the overly eager creation of the pid file you could add a delay to the shell script and then check to make sure the process is still running before writing the pid file. But how long should the delay be? A better way is to take advantage of the fact the a shell will not exit while a program is attached to its standard out or error — even if the process is running in the background. We know that our program will not detach from those until the startup process is complete. The following shell script achieves this

#!/bin/sh

launch_daemon()
{
  /bin/sh &lt;&lt;EOF
     java -Ddaemon.pidfile=mydaemon.pid -cp your_class_path com.domain.main_class &lt;&amp;- &
     pid=\$!
     echo \${pid}
EOF
}

daemon_pid=`launch_daemon`
if ps -p "${daemon_pid}" &gt;/dev/null 2&gt;&1
then
  # daemon is running.
  echo ${daemon_pid} &gt; mydaemon.pid
else
  echo "Daemon did not start."
fi

This script starts a sub-shell and launches the daemon (in the launch_daemon() function). The sub-shell will only return once the java program has detached from the console — for our program that means it has completed its startup or died. After the launch_daemon() function returns we check to see if the pid it started is still running. If so it means that the daemon started correctly and the we write the daemon’s pid to the pid file. Remember that whenever the daemon’s VM shuts down the pid file will be deleted so you can treat the existence of the pid file as an indication that the process is running.

Now it occurs to you that if a problem occurs during startup you really would like to log it to both the log file and console. Since you are using log4j this is pretty straight forward. Just updated you main method like the following

static public void main(String[] args)
{
   Appender startupAppender = new ConsoleAppender(new SimpleLayout(), "System.err");
   try
   {
       logger.addAppender(startupAppender);
       // do sanity checks and startup actions
       daemonize();
   }
   catch (Throwable e)
   {
       logger.fatal("Startup failed.",e);
   }
   finally
   {
      logger.removeAppender(startupAppender);
   }

   // do infinite loop
}

where “logger” is a static member variable that contains a Logger object. The nice thing about this is you can log message anywhere in you startup code and know that someone will see them, even if it occurs before you have configured the logging based on the application configuration. If the normal application logging is configured, the messages will go both to the console and to the log file for future debugging.

So all that works pretty well. There is another problem though. There is not a clean way to shut this daemon down. We need a graceful way to handle shutdown. So we add the following code to our main class

static protected boolean shutdownRequested = false;

static public void shutdown()
{
   shutdownRequested = true;
}

static public isShutdownRequested()
{
   return shutdownRequested;
}

Then we update our application so that occasionally it checks ‘isShutdownRequested()’ and if it is we leave the main loop. Now our main method looks like

static public void main(String[] args)
{
   Appender startupAppender = new ConsoleAppender(new SimpleLayout());
   try
   {
       logger.addAppender(startupAppender);
       // do sanity checks and startup actions
       daemonize();
   }
   catch (Throwable e)
   {
       logger.fatal("Startup failed.",e);
   }
   finally
   {
      logger.removeAppender(startupAppender);
   }

   while(!isShutdownRequested())
   {
      // wait for stimuli
      // process stimulus
   }
}

This looks pretty good but you still only shutdown from inside the program. The solution is a VM shutdown hook. The is a bit of code that the VM runs when it is shutdown. We create the following method

static protected void addDaemonShutdownHook()
{
   Runtime.getRuntime().addShutdownHook( new Thread() { public void run() { MainClass.shutdown(); }});
}

and update the shutdown method as follows

static public void shutdown()
{
   shutdownRequested = true;

   try
   {
       getMainDaemonThread().join();
   }
   catch(InterruptedException e)
   {
       logger.error("Interrupted which waiting on main daemon thread to complete.");
   }
}

Note that we now wait for the main daemon thread to die. This is because the VM waits for the VM shutdown hooks to complete for exiting but it does not wait for other threads to complete. This join allows the main daemon threads to complete in a controlled way rather than being killed by the VM. Then we update the main method to call this new addDaemonShutdownHook() method

static public void main(String[] args)
{
   Appender startupAppender = new ConsoleAppender(new SimpleLayout());
   try
   {
       logger.addAppender(startupAppender);
       // do sanity checks and startup actions
       daemonize();
       addDaemonShutdownHook();
   }
   catch (Throwable e)
   {
       logger.fatal("Startup failed.",e);
   }
   finally
   {
      logger.removeAppender(startupAppender);
   }

   while(!isShutdownRequested())
   {
      // wait for stimuli
      // process stimulus
   }

   // do shutdown actions
}

Now you can kill the process using kill `cat mydaemon.pid` but shutdown will be orderly and controlled.

So there you have it. A fairly safe and full featured way of create a Unix daemon with Java. Of course, if you do not need the extra control and do not mind have native binaries it might be easier to use Jakarta Daemon.

{Update: corrected a variable name in one of the shell scripts and added a needed closing brace to one of the bits of Java code}

Comments 78

  1. mike wolf wrote:

    great article, now heres a question for you, how do you keep it running after logout? I add nohup, and then have to redirect the output, any ideas?

    Posted 21 Dec 2005 at 1:02 pm
  2. Peter Williams wrote:

    The above code will continue running when you log out. The combination of closing the input stream on execution (the “

    Posted 21 Dec 2005 at 5:09 pm
  3. mike wolf wrote:

    so by doing System.out.close and system.error.close, you essentially are disconnecting from the login anyways… because its no longer connected to an out?

    Posted 22 Dec 2005 at 8:55 am
  4. mike wolf wrote:

    i answered my own question that does work.. pretty sweet.

    Posted 22 Dec 2005 at 1:01 pm
  5. Peter Williams wrote:

    Stupid html santization broke my last comment, sorry. :)

    You have the right idea. By closing System.in, System.out and System.err the process is effectively disconnected from the terminal. The only real effect of this technique from the programs perspective is that System.out is close so that it cannot be written to. But generally we write stuff to the logs anyway. :)

    Posted 22 Dec 2005 at 1:02 pm
  6. Peter Williams wrote:

    BTW, note that System.in is closed when the java process is started by the “&<-” addition to the command line.

    Posted 22 Dec 2005 at 1:04 pm
  7. mike wolf wrote:

    thanks… peter your blog entry helped me alot in getting this app transitioned to a unix service. I would like to contribute to your list of things to hate about java,

    -there is too much documentation and not enough of it to the point

    I had to take a windows service written in C# on windows and port it to run on unix, the port went ok, but finding realistic documentation on then deploying it as a unix daemon was few and far between. usenet groups a documentation does not make.

    Posted 28 Dec 2005 at 12:39 pm
  8. Peter Williams wrote:

    Glad I could help. I also find it odd that there is so little support for using Java as daemon/service. Especially since that seems to be the primary use for Java these days.

    Posted 28 Dec 2005 at 5:59 pm
  9. Phi Nguyen wrote:

    When I ran your script, it just hung at the line “daemon_pid=`launch_daemon`”. The only way I can make the script continue is to kill the java process. So my question is that how do I make the java process to tell the script that “it has completed its startup”?

    Thanks

    Posted 07 Jun 2006 at 11:00 am
  10. Peter Williams wrote:

    Phi,

    The code you are looking for is:

    System.out.close();
    System.err.close();

    That will detach the java process from shell and allow the shell script to continue. In the article it is found in the `daemonize()` method.

    Posted 08 Jun 2006 at 9:25 am
  11. Ryan Shelley wrote:

    I’m a bit confused. You use the method: getMainDaemonThread(), however, I don’t see it declared anywhere. Maybe it’s in another blog entry that I’m missing, and if so, can you make a reference it? Thanks!

    Posted 14 Jul 2006 at 7:56 pm
  12. Ryan Shelley wrote:

    I also noticed the same thing with regards to your “daemonize()” method. Can you clarify?

    Posted 14 Jul 2006 at 8:13 pm
  13. Ryan Shelley wrote:

    Scratch the daemonize comment.. I wasn’t being very observant.

    Posted 14 Jul 2006 at 8:14 pm
  14. Peter Williams wrote:

    Ryan,

    I did fail show the tracking of the thread. For this to work, you need to store the current thread during the deamonize() method in a member variable and getMainDaemonThread() returns that thread.

    Posted 16 Jul 2006 at 10:32 pm
  15. Ryan Shelley wrote:

    Ok. So for those who come after me, this is what I added and it seems to work just fine (if this comes out unformatted, my apologies):

    static private Thread mainThread;

    static private Thread getMainDaemonThread()
    {
    return mainThread;
    }

    static public void daemonize()
    {
    mainThread = Thread.currentThread();

    System.out.close();
    System.err.close();
    }

    Posted 17 Jul 2006 at 4:16 pm
  16. François Rouxel wrote:

    Hi, I think your java solution daemon is great. I will build on it. Anyway, I would have a specific additional need: I would like that the daemon be able to receive commands (from the command line) like restart, trace, etc. Your solution does provide the required persistancy. I suppose that the “System.in.close()” line, wich kills terminal dependancy, makes impossible input command solution.Am I correct? Thanks in advance for your help. Regards, François.

    Posted 01 Aug 2006 at 6:54 am
  17. Peter Williams wrote:

    The closing ‘System.in’ does make sending commands more difficult.
    However, I can imagine several ways to send commands to a daemonized
    process.

    * a Posix compatibility library for Java would allow you to use
    standard Unix signals like HUP, TERM and USR1 using the kill
    command the

    * daemonized process could open socket (probably a Unix domain
    socket) when it was start and listen for commands sent on that socket

    * files with commands in them could be created in a temporary
    directory and the daemonized process could poll the directory for
    new commands

    All of these approaches would work. To my taste the second one seems
    the most elegant because it does not require an native library like
    the first one and does not require directory polling like the last
    one. However the second choice is probably the most work.

    Posted 07 Aug 2006 at 8:23 am
  18. JohnZaf wrote:

    How can be done in windows?
    Not with all the functionality you presented, just the main stuff.

    Thanks in advance.

    Posted 11 Aug 2006 at 8:48 am
  19. Peter Williams wrote:

    I really don’t know. You might take a look at [this](http://support.microsoft.com/default.aspx?scid=support.microsoft.com:80/support/kb/articles/q137/8/90.asp&NoWebContent=1) or something like [FireDaemon](http://www.firedaemon.com/). I have no knowledge of either but they might work for you.

    Posted 11 Aug 2006 at 10:02 pm
  20. Hung wrote:

    Pete,

    I have trouble getting the rest of the code for the method addDaemonShutdownHook. The wepage got cut off for some reason. Can you send me the rest ?

    Posted 31 Aug 2006 at 10:04 pm
  21. Loïc Minier wrote:

    Hi,

    I tried verifying that:
    “The sub-shell will only return once the java program has detached from the console”

    With the following shell snippet:
    !/bin/sh

    set -e

    start() {
    /bin/sh <!/usr/bin/env python

    from time import sleep

    print “daemon start”
    sleep(5)
    print “daemon end”

    Calling the shell snippet results in:
    bee% ./foo.sh
    pid=7400
    returned
    bee% daemon start
    daemon end

    Note how I immediately get a prompt back and how “returned” is printed way before daemon end. It doesn’t seem to me that the foo.sh /bin/sh is waiting for the inlined /bin/sh sub-shell to return.

    However, I could verify that the my-daemon process outlives the shell, even if I close the terminal (xterm) from which I am doing the tests.

    Bye,

    Posted 13 Dec 2006 at 5:27 am
  22. Howard wrote:

    Hi!

    Great article …if I only could get it to work ;)

    I’ve been messing around with the shell script, but all I get is “Daemon did not start.”.

    Seems like the daemon_pid string contains the pid twice. The following code:

    ...[snip]...
    daemon_pid=`launch_daemon`
    echo ${daemon_pid}
    if ps -p "${daemon_pid}" >/dev/null 2>&1
    ...[snip]...
    

    prints the following:
    3453 3453
    Daemon did not start.

    ..if the PID was 3453. In other words it seems like the if-statement won’t give a match.

    Can anyone spot the problem?

    I run this under Fedora Core 6.

    Best regards!:)

    Posted 13 Dec 2006 at 1:59 pm
  23. Peter Williams wrote:

    Howard,

    The only thing I can think of is that you might have added some debug printing to the launch_daemon function? Any additional calls to echo in that function will break it.

    If the above is not the problem I would added some delimitation around the echo to make sure that the value of daemon_pid is really broken and it is not just getting printed twice. For example,

    echo ">>>>${daemon_pid}<<<<<"
    
    Posted 27 Dec 2006 at 9:52 am
  24. Will wrote:

    Thank you for this information. It has proved very usefull.

    Posted 12 Mar 2007 at 10:26 am
  25. Arun wrote:

    How to run a shell script from a java program in new terminal window,not in my programs’ console. since my shell script will hold the step by step process to start my uml in terminal. plz give ur idea n this?

    Thanks in advance…

    Posted 29 Mar 2007 at 7:06 pm
  26. Matt Busche wrote:

    A wonderful artical. Thanks Peter! Here are three comments:

    Comment #1

    If you want to add debug to launch_daemon you can do this:

    echo “my debug output” 1>&2

    1>&2 redirects stdout to stderr and will not intefere with the correct capture of the pid by the invoking shell script.

    Comment #2

    I had a similar expereience to Loïc Minier. I don’t know python so I did not try to analyze his script but I believe I have finally figured out what is going on. I think your statement “The sub-shell will only return once the java program has detached from the console — for our program that means it has completed its startup or died.” is inaccurate. launch_daemon does NOT block waiting for stdout/stderr of the daemon to close. It’s the fact that you execute launch_daemon in back-tics that is causing execution to block until stdout is closed.

    I think that when you invoke a shell function or program in back-tics the stdout from that program is redirected to the outter shell script (so it can be processed as part of that outter shell script in-line). It makes sense to me that shell back-tic processing would wait for the stdout of that subshell to close before passing the results back to the outter shell. If you don’t use back-tics, then the stdout of the subshell is tied to the stdout of the outter shell and nothing is waiting for that stream to close, so everything just keeps going. Mind you, I really don’t know what I’m talking about — my explanations are just theories. :)

    Comment #3

    I’ve written some reusable shell functions that allow you to invoke the java program directly from an init.d script. I won’t post them all here, but perhaps some may find my variation on launch_daemon useful in that it allows you to kick the thing off as a different user:

    launch_daemon()
    {
    daemonUid=$1
    daemonCommandLine=$2

    su - $daemonUid -c "/bin/sh <<EOF
        $daemonCommandLine <&- &
        echo \\\$!
    

    EOF”
    }

    Which you can invoke like so:

    daemonpid=launch_daemon someuser "java com.mycompany.MyDaemon"

    Thanks again!
    Matt Busche

    Posted 26 Apr 2007 at 11:07 am
  27. Matt Busche wrote:

    Ugh. After all that talk of back-tics, I left them off in that example in comment 3. Should be:

    daemonpid=launch_daemon someuser "java com.mycompany.MyDaemon"

    Matt Busche

    Posted 27 Apr 2007 at 2:53 pm
  28. Okpor Lawrence wrote:

    I really like your write-up on Daemons, at least i now have a nrw insight into what it is all about. Thanks

    Posted 01 Jun 2007 at 1:39 pm
  29. Frederik Van Goolen wrote:

    Thanks for this very informative article on daemons.

    Posted 25 Jun 2007 at 1:37 am
  30. Guy Sherman wrote:

    Hi There,

    Thanks for the great information. I am just wondering how to prevent the service from consuming loads of CPU time when it is just listening. I have quite a few internal threads, will calling Thread.yield() in all of my run loops lower the idle cpu usage?

    Posted 10 Jul 2007 at 7:02 pm
  31. Peter Williams wrote:

    Guy,

    If I recall my Java threading model correctly, calling Thread.yield
    will have no effect unless you are using green threads (and even then
    it will probably not have any noticeable effect) . You need to add
    some sort of blocking read to your loops so that they just wait until
    there is new data or a new connection to handle. Alternatively, you
    could add a sleep to the processing loop but that would be a distance
    second choice as far I am concerned.

    Posted 11 Jul 2007 at 9:15 am
  32. luau wrote:

    This blog post is completely awesome. I haven’t seen this documented in any book or anywhere else on the Internet.

    It surprises me to learn that there really isn’t anything “special” about a Linux daemon process.

    I am happy to report that the above code works great with /etc/init.d/ and /sbin/service

    Posted 20 Aug 2007 at 4:24 pm
  33. MarkD wrote:

    Linux seems to return more than one pid.

    Try daemon_pid=launch_daemon | head -1

    Posted 31 Aug 2007 at 8:28 am
  34. Randy Rizun wrote:

    I tried to above

    daemon_pid=launch_daemon | head -1

    but it didn’t quite work for me (fedora 7)… I found that having the pipe to head in there caused the backquotes to return “early” before err/out were closed, defeating the whole purpose of the mechanism…

    I got it to work by putting the “head” in its own separate step:

    daemon_pid=launch_daemon
    daemon_pid=echo ${daemon_pid} | head -1

    (NOTE- backquotes are probably missing in this blog post comment (stripped out by the blog software) but they most certainly need to be in there just like in the original post)

    Great post! Thanks!!!

    Posted 11 Nov 2007 at 12:39 pm
  35. 터프가이 wrote:

    모니이게?

    Posted 29 Jan 2008 at 11:12 pm
  36. Daniel Savard wrote:

    I made some modifications to the original skeleton to replace the shell script by a Perl script. The Perl script is forking the child process and launching the Java daemon, the Java daemon open a named pipe created by the Perl script for writing and the parent process is opening the named pipe for reading. While initialization of the Java daemon is done, a message is sent in the named pipe and the Perl parent program resume execution creating the pid file. I also added the verification for the pid file prior starting the Java daemon in the Java daemon as part of initialization to avoid starting two instances of the same daemon.

    I am locking the PID file in the Perl script, but this is not really necessary, remanent code from testing an approach with file locks.

    Here is the Perl script:

    !/usr/bin/perl

    #
    #
    use Env;
    use Fcntl ‘:flock’;
    use File::Basename;
    use Shell qw(mkfifo);

    $pidfile=’/var/tmp/’ . (split(/./,basename($0)))[0] . ‘.pid’;
    $fifoname = ‘/var/tmp/.’ . (split(/./,basename($0)))[0] . ‘.fifo’;
    $classpath=$ENV{CLASSPATH} . ‘:yourclasspath’;
    $ENV{CLASSPATH} = $classpath;
    unlink($fifoname);

    sub start_daemon() {
    push(@javadaemoncmd,”java”);
    push(@javadaemoncmd,”-Ddaemon.pidfile=” . $pidfile); push(@javadaemoncmd,”com.acme.coyote.testing.RRCatcherDaemon”);
    push(@javadaemoncmd,$fifoname);
    push(@javadaemoncmd,”<&-”);
    push(@javadaemoncmd,”&”);

    my $rc = 0;
    if ( mkfifo($fifoname) == 0 ) {
      my $cpid = fork();
      if ( $cpid == 0 ) {
        exec(@javadaemoncmd);                                                     
      }
    
      $rc = $cpid;
      # Read from the pipe what the Java program has to say
      $output = '';
      if ( open(RJAVA, "< $fifoname") ) {
        while ( <RJAVA> ) {
      $output = $output . $_;
      if ( /$^Initialization completed.*/ ) {
        $rc = $cpid;
      }
        }
        close(RJAVA);
      }
    }
    return(($rc,$output));
    

    }

    my $rc = 0;
    my ($dpid,$message) = start_daemon();
    unlink($fifoname);

    if ( $dpid ) {
    kill(0,$dpid);
    my $code = $?;
    if ( $code eq 0 ) {
    if ( open(PIDFILE,”>>$pidfile”) ) {
    flock(PIDFILE,LOCK_EX);
    print PIDFILE $dpid;
    flock(PIDFILE,LOCK_UN);
    close(PIDFILE);
    } else {
    $rc = 1;
    print “Cannot open pid file \”" . $pidfile . “\”.n”;
    }
    } else {
    print “Process: “, $dpid, ” no longer present.n”;
    print $message, “n”;
    }
    } else {
    $rc = 2;
    print $message, “n”;
    }

    exit($rc);

    I wrote three methods: openFifo(), closeFifo() and sendFifo() which I use in the Java daemon initialization phase. As soon as the named pipe (FIFO) is opened, the System.err and System.out can be closed since all messages between the Perl parent script and the Java daemon will pass through the named pipe.

    Posted 10 Mar 2008 at 5:03 pm
  37. DP wrote:

    Thanks for the excellent tutorial Peter. I was able to create a java-based daemon modeled after your approach and saved hours (probably days?) of time. Great job!

    Posted 02 May 2008 at 9:18 am
  38. Prakash wrote:

    I have a requirement to write a java daemon in Unix, which will be an java application. For example say abc.java. which should print “hello world” whenever i call the application. I have few questions is -
    How to make a call to a daemon ?
    Do i have to extend Thread in my abc.java class to runn continuesly in the background?

    Thanks

    Posted 02 May 2008 at 1:13 pm
  39. Arkadiy Vertleyb wrote:

    Hi Peter,

    I daemonized my java application using your method, and everything looked great until QA run it over SSH. Turns out it causes the SSH to hang on exit. SSH also kills the app if the output is redirected on the command line :-(

    I am using Redhat.

    Any ideas?

    Thanks,
    Arkadiy

    Posted 27 May 2008 at 3:23 pm
  40. Peter Willams wrote:

    Arkadiy Vertleyb,

    That is weird. I developed this approach to daemonization precisely to avoid the hanging/killing that normally takes place when you launch an app over ssh. To be perfectly honest I have any contact with a system using this approach in several years so debugging your problem could be difficult for me. :)

    Posted 27 May 2008 at 5:51 pm
  41. MJK wrote:

    I am having trouble getting this to work under Solaris 10. I’m using the CDE and open a terminal window to start my app. I switch to root and just execute the command line:
    java -cp your_class_path com.domain.main_class <&- 1>/dev/null 2>&1

    (I’m just trying to get the program to continue to run atm).

    The program executes normally, however when I close the terminal window (via exit, exit) my application goes away.

    Any clues as to what I might be doing wrong? I even added the Daemonize routine to close stdin, stderr and stdout, but it still stops when the terminal window is closed.

    Posted 29 May 2008 at 7:53 am
  42. James Goode wrote:

    Thanks for this article, it’s exactly what I needed to know in order to continue with my project.

    Posted 30 May 2008 at 5:17 am
  43. gnuview wrote:

    Thanks for this post, found it in the nick of time!

    Posted 18 Jun 2008 at 5:24 am
  44. Greg wrote:

    Thanks for the post Peter. Very useful stuff!

    Posted 23 Jun 2008 at 12:00 pm
  45. Carl wrote:

    Hi,
    I have some trouble getting the Shutdown Hook to work.
    When I start my Application in a unix environment with “java -cp your_class_path com.domain.main_class” and then whant to kill it via “CTRL-C” there is no problem and the Shutdown sequence executes normally.
    But as soon as I try to start my app as a daemon process with “java -cp your_class_path com.domain.main_class &” and then try to kill it with “kill -INT ” I just get an interrupt message on the console and the ShutdownHook does not execute.
    Any idea whats wrong with that ?

    Posted 09 Aug 2008 at 8:24 am
  46. Juan Luis Baptiste wrote:

    Hi,

    I’m trying your code but I don’t see that closing stout and sterr detaches the process from the shell, what it’s detaching it from it is the & at the end of the excecution of the java process on the shell script. If you remove the <&- & from that line it wont detach by it self as you say, it will continue to execute without returning control to the shell from where it was invoked, or I’m understanding wrongly when you say that closing stdout and stderr will detach the process from the shell that invoked it. What I’m hoping to do is to make the java process detach it self and return the control to the shell that invoked it without adding an & at the end of line of execution, which defeats the idea of “daemonizing” a process process by making it detach by it self.

    Posted 29 Sep 2008 at 9:27 am
  47. Peter Williams wrote:

    Mr Baptiste,

    Closing stderr and stdout prevents the Java process from terminating when the shell does. The & at the end of the Java command causes it to be executed the background. You need both to make this approach work.

    Posted 29 Sep 2008 at 12:58 pm
  48. Juan Luis Baptiste wrote:

    Hi,

    I found another approach to what I was looking for:

    http://kim.tensta.gannert.se/projects/jada/

    It works without having to add the & to run on the background, just install jada and make your program create a thread and jada will automatically make it run on the background.

    Posted 29 Sep 2008 at 4:25 pm
  49. Lalit Kumar wrote:

    Peter

    I just tried your solution and it worked without any problems. I was able to stop the process by killing it as you described. I even closed the command window and it continued to run and that’s what I wanted. Before that I was struggling to find a solution for it on AIX 64bit. I tried a solution from tanukisoftware but it did not run on 64bit version, although it was fine on windows platform. Thanks

    Posted 23 Oct 2008 at 5:40 pm
  50. Chris wrote:

    Thanks for this introduction brought light to my missing knowledge!

    thank dude!

    Cheers Chris

    Posted 24 Oct 2008 at 12:11 am
  51. Albrecht Weiser wrote:

    Peter
    that looks very auspicious for me, so i will try that for a linux-daemon. But there is one thing not clear for me:
    For my understanding of your program i have to implement all my program-logic inside the infinite loop that it works properly to shutdown in a controlled way. If i build a second thread outside the loop, this thread isn’t shutdown save. Is that statement right so far?
    Best regards
    Albrecht

    Posted 30 Dec 2008 at 2:28 am
  52. berendona wrote:

    Thanks a lot. Your post was very helpful. I am using your hint (in a modified way) in my small project.

    Posted 05 Jan 2009 at 7:01 am
  53. Chris Patti wrote:

    I love the post. It really nicely crystalizes the issues around daemons in Java, and made for a nice refresher both for myself and the developer of some otherwise well behaved code that was causing problems in our build process because it was hanging on to stdout and stderr.

    Posted 14 Jan 2009 at 11:22 am
  54. Ozeroff wrote:

    Very useful files search engine. http://myrapida.com is a search engine designed to search files in various file sharing and uploading sites.

    Posted 17 Mar 2009 at 12:19 pm
  55. Albrecht Weiser wrote:

    Hi,
    I implemented everything like described above.
    But when calling my program with ‘java -cp your_class_path com.domain.main_class <&- &’ and close the console it nevertheless quits the launched program. I also tried with ‘-cp your_class_path com.domain.main_class <&- 1>/dev/null 2>&1 &’.
    No way. When i close the terminal-window, the program quits. I debugged my app. It surely steps into the daemonize-method and closes System.err and System.out.
    I’m using a Suse Linux 10.X and connect over SSH (secure shell).
    What’s going wrong there?

    Posted 18 Mar 2009 at 4:52 am
  56. Rick wrote:

    Hi Peter,
    I’m trying to run your program & I’m getting below error:

    getPidFile() & getMainDaemonThread not defined.

    Can you please help me out? I’m new to this daemon program…

    Thanks in Advance!

    Posted 01 Apr 2009 at 12:30 pm
  57. Mar wrote:

    Great post. this definitely fills a gap in the Java curriculum

    Thanks

    Posted 17 Apr 2009 at 12:31 pm
  58. Rick L wrote:

    Hi,
    I want to run the daemon program which will do following:

    1. Get records from postgres database for status=active.
    2. For each record, perform some processing logic & then insert them into another database.

    Now, the question here is if my daemon is done processing all active records, then I really want it in sleep mode rather than using CPU unecessarily.

    My question for Peter is can I make use of your daemon code? If so, how do I take care of not using CPU continously?

    Thanks!

    Posted 05 May 2009 at 3:05 pm
  59. Peter Williams wrote:

    Rick,

    You could definitely do that. Just put a sleep in the infinite loop. The loop would grab all the active records, do what ever it need to do for each of them, then sleep for an appropriate amount of time.

    Posted 05 May 2009 at 9:14 pm
  60. Rick L wrote:

    Hi Peter,
    Thanks for the reply. However, in that case, I’ll have to hard code the time to go in sleep mode, right?
    Also, is it possible that the program will go in infinite sleep & it should wake up when some button from UI is clicked for waking this daemon? If so, how can it be done with your program?

    Thanks!

    Posted 28 May 2009 at 11:54 pm
  61. Raman wrote:

    Hi Peter,
    I’m using ur daemon. But I founf a very big flaw in this code ….Since the loop is forever true, if I restart the database in between, it goes to exception block & then starts logging error to log file. In couple of seconds, the log files goes HUGE & finally 0 disk space!!!

    while(true) is a BAD idea.
    

    Any suggestion for this problem???

    Thanks!

    Posted 25 Jun 2009 at 4:06 pm
  62. Raymond Marfurt wrote:

    Hi Peter,

    I have used your method for years without any problems – thanks so far!!

    Since the latest ubuntu update, the daemon does not start correctly when booting. The daemon starts (I get my log entries, the java app works fine), but then gets terminated after 5 secs.

    I don’t see any information in a log file. Do you have any hint how to analyse this?

    Posted 05 Aug 2009 at 6:33 am
  63. Raymond Marfurt wrote:

    I forgot to mention: while the system is up and running, I can still perfectly start/stop my daemon.

    Posted 05 Aug 2009 at 6:41 am
  64. Arun wrote:

    Peter – Thanks for the tutorial. Very helpful. Here is a missing piece for others.

    static public File getPidFile ()
    {
    return new File(System.getProperty(“daemon.pidfile”));
    }

    Posted 02 Sep 2009 at 12:50 pm
  65. Frank O'Gorman wrote:

    Hi Peter

    I don’t know what shell or terminal you are using, but with bash and a standard xterm closing System.in, System.out and System.err makes no difference to whether a hangup signal is sent to the java process.

    Closing the xterm by clicking the X button causes a hangup signal to be sent. Closing the xterm by typing ‘exit’ or cntrl-D does NOT cause a hangup to be sent. In neither case does closing the input/output make any difference to the behaviour.

    Do you have something other than the hangup signal in mind when you say that the “shell will not kill the program”?

    Posted 09 Sep 2009 at 8:00 am
  66. basu008 wrote:

    Awesome post. Helped me understand all the nuances of daemoning a java class

    thanks

    Posted 06 Dec 2009 at 6:49 am
  67. Sachin Jain wrote:

    Hi

    I am using a client server program for my project. The problem that i am having is that i run the server in the background. It runs perfectly but after some time say 10-12 days even though the program is running which I can see by using the Unix command ps- u project, there is no response from the server. Please can any one tel me what the problem is????. The command that I am using to run the server in the background is :

    nohup command 2>/dev/null 1>/dev/null &

    Thanks

    Posted 11 Jan 2010 at 8:22 am
  68. Jeremy Brooks wrote:

    Good post. The only downside I can see here is that you might miss errors that are dumped to stdout/stderr, for example out of memory errors.

    Posted 19 Jan 2010 at 11:07 am
  69. Jeremy Brooks wrote:

    Sorry, forgot to include my solution for capturing stderr/stdout when needed:

    if (System.getProperty(“detach”).equals(“false”)) {
    // Log message about no detach or something
    } else {
    System.in.close();
    System.out.close();
    System.err.close();
    }

    Now if you are getting weird crashes and expect that you may have an out of memory error or something that is getting printed to stderr, just include the -Ddetach=false system property in your startup command. When you have captured the information you need, remove the system property, or set it to anything other than false, and your program will detach as expected.

    Posted 19 Jan 2010 at 11:27 am
  70. Jeff Shaver wrote:

    What is the solution in the case where the JVM ignores ‘kill ‘ ? TERM, HUP, INT, and QUIT are all ignored. KILL, and USR1 do kill it, but the shutdown() code does not get run.

    Thanks for a very useful article.

    Posted 03 Jun 2010 at 11:51 am
  71. Scott the Werewolf wrote:

    Sounds impressive, but what would you use this java program for? Sorry for asking what may be a silly question…. =P

    Posted 14 Aug 2010 at 11:18 pm
  72. Avi wrote:

    Thanks for this artical. I have learned a lot.

    Posted 27 Jan 2011 at 10:31 am
  73. Ron de Jong wrote:

    Hi Peter,

    Very appreciated all in all, but you’re completely ignoring the main java principle:

    PLATFORM INDEPENDENCY !!!

    Your solution needs to work on:
    Microsoft OS’s to!!! so forget about those shell solutions!!!

    Posted 14 Apr 2011 at 3:46 am
  74. Vineet wrote:

    Good article.

    However, I am seeing the same problem that Jeff Shaver is facing. I am running on Iced Tea JVM on Linux and the shutdown hook does not get executed when I kill the application.

    Anyone else facing this problem?

    Posted 24 Jun 2011 at 1:24 am
  75. Eric wrote:

    I have a working Daemon my problem is when it is run from services (i.e. Server reboots) The Jar is running and responding to status checks but exec() passthrus to Linux do not return or get executed

    Posted 17 Aug 2011 at 2:22 pm
  76. Pablo wrote:

    The DaemonShutdownHook doesn’t hold the app to finalize, you must not finalize the shutdown method till you end the main thread. Why? Because after the shutdown method the Signal continues with System.exit, that means that if you didn’t end your tasks before that, you’re going to leave lines without execution. My way to fix it was:

    static public void shutdown()
    {
    shutdownRequested = true;
    while (!MainClass.endFlag){//put some wait if u want}
    }

    static public void main(String[] args)
    {
    endFlag=false;
    Appender startupAppender = new ConsoleAppender(new SimpleLayout());
    try
    {
    logger.addAppender(startupAppender);
    // do sanity checks and startup actions
    daemonize();
    addDaemonShutdownHook();
    }
    catch (Throwable e)
    {
    logger.fatal(“Startup failed.”,e);
    }
    finally
    {
    logger.removeAppender(startupAppender);
    }

    while(!isShutdownRequested())
    {
    // wait for stimuli
    // process stimulus
    }

    // do shutdown actions
    //end thread shutdown hook
    endFlag=true;
    }

    Posted 26 Aug 2011 at 7:51 am
  77. VaderJM wrote:

    This was a fantastic post. I was able to get a service running in only a couple days (saved me tons of time). Thank you.

    Posted 10 Nov 2011 at 10:48 am
  78. Joao Thomazini Neto wrote:

    Amazing information. Right on target. Many thanks.

    Posted 17 Jan 2012 at 3:46 pm

Trackbacks & Pingbacks 4

  1. From links for 2006-08-22 at DavorS.eu LinkBlog on 21 Aug 2006 at 7:19 pm

    [...] Peter Williams » Java Daemon saved me a few hours… (tags: Java) [...]

  2. From Nice way to shutdown your application « When IE meets SE on 16 Jul 2007 at 4:54 pm

    [...] Using a daemon thread with ShutdownHook For example, JBoss uses shutdownHook.setDaemon(true) or do this (Java Daemon). [...]

  3. From Daemonize a java process » qwerpo on 03 Jun 2009 at 9:30 am

    [...] Found this nice article about daemonizing a Java process. [...]

  4. From What is Tridium? | Building Automation Monthly on 16 Jul 2012 at 7:33 pm

    [...] Daemon- The Daemon processes or as I call them VM background services. Is the functionality to run the background processes that a user does not need to see but are vital for  the station to function. If you are a geek like me and you want to know more about Java Daemons, you can read about them here and here. [...]