Safe daemonization from within Java
Switch branches/tags
Pull request Compare This branch is 10 commits behind brianm:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Gressil uses jnr-ffi to provide daemonization and "forking" for Java processes. It uses posix_spawn to achieve this, rather than fork and exec. Spawn is used, rather than the standard C world idiom of fork followed by exec as fork is very unsafe on the JVM -- there is no such thing as a critical section which cannot get splatted by GC reshuffling pointers. Here, the child process is started by spawning a new process complete with command line, not by forking the state of the parent process.

Usage for daemonization looks like:

package org.skife.gressil.examples;

import org.skife.gressil.Daemon;

import java.util.Arrays;
import java.util.Date;

import static org.skife.gressil.Daemon.remoteDebugOnPort;

public class ChattyDaemon
    public static void main(String[] args) throws IOException
        new Daemon().withMainArgs(args)
                    .withPidFile(new File("/tmp/"))
                    .withStdout(new File("/tmp/chatty.out"))
                    .withExtraMainArgs("hello", "world,", "how are you?")

        while (!Thread.currentThread().isInterrupted()) {
            System.out.println(new Date() + " " + Arrays.toString(args));
            try {
            catch (InterruptedException e) {

In the parent process the call to Spawn#daemonize() will call System.exit(), in the child process it will return normally.

The child process, in this case, will also wait for a Java debugger to attach on port 5005. It will attach stdout to /tmp/chatty.out, and stdin and stderr will default to /dev/null (which stdout would also attach to by default if it were not specified).

The easiest way to get started is via maven: