Skip to content
Safe daemonization from within Java
Java
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
src
.gitignore
LICENSE
NOTICE
README.md
pom.xml

README.md

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.io.File;
import java.io.IOException;
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/chatty.pid"))
                    .withStdout(new File("/tmp/chatty.out"))
                    .withExtraMainArgs("hello", "world,", "how are you?")
                    .withExtraJvmArgs(remoteDebugOnPort(5005))
                    .daemonize();

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

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:

<dependency>
  <groupId>org.skife.gressil</groupId>
  <artifactId>gressil</artifactId>
  <version>0.0.4</version>
</dependency>
Something went wrong with that request. Please try again.