I have a Java program that I'd like to daemonize on a linux system. In other words, I want to start running it in a shell and have it continue running after I've logged out. I also want to be able to stop the program cleanly.
I found this article which uses a combination of shell scripting and Java code to do the trick. It looks good, but I'd like something simpler, if possible.
What's your preferred method to daemonize a Java program on a Linux system?
Properties of Java Daemon Thread They can not prevent the JVM from exiting when all the user threads finish their execution. JVM terminates itself when all user threads finish their execution. If JVM finds a running daemon thread, it terminates the thread and, after that, shutdown it.
A daemon thread is a thread that does not prevent the JVM from exiting when the program finishes but the thread is still running. An example for a daemon thread is the garbage collection. You can use the setDaemon(boolean) method to change the Thread daemon properties before the thread starts.
The setDaemon() method of the Thread class is used to mark/set a particular thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
Apache Commons Daemon will run your Java program as Linux daemon or WinNT Service.
If you can't rely on Java Service Wrapper cited elsewhere (for instance, if you are running on Ubuntu, which has no packaged version of SW) you probably want to do it the old fashioned way: have your program write its PID in /var/run/$progname.pid, and write a standard SysV init script (use for instance the one for ntpd as an example, it's simple) around it. Preferably, make it LSB-compliant, too.
Essentially, the start function tests if the program is already running (by testing if /var/run/$progname.pid exists, and the contents of that file is the PID of a running process), and if not run
logfile=/var/log/$progname.log pidfile=/var/run/$progname.pid nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1
The stop function checks on /var/run/$progname.pid, tests if that file is the PID of a running process, verifies that it is a Java VM (so as not to kill a process that simply reused the PID from a dead instance of my Java daemon) and then kills that process.
When called, my main() method will start by writing its PID in the file defined in System.getProperty("pidfile").
One major hurdle, though: in Java, there is no simple and standard way to get the PID of the process the JVM runs in.
Here is what I have come up with:
private static String getPid() { File proc_self = new File("/proc/self"); if(proc_self.exists()) try { return proc_self.getCanonicalFile().getName(); } catch(Exception e) { /// Continue on fall-back } File bash = new File("/bin/bash"); if(bash.exists()) { ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID"); try { Process p = pb.start(); BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream())); return rd.readLine(); } catch(IOException e) { return String.valueOf(Thread.currentThread().getId()); } } // This is a cop-out to return something when we don't have BASH return String.valueOf(Thread.currentThread().getId()); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With