Skip to content
Safe daemonization from within Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit 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 Daemon#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:

You can’t perform that action at this time.