Daemonizing and launching subprocesses on JRuby with Spoon and posix_spawn

A common question people ask about JRuby is “why doesn’t work on JRuby?”

Usually the answer is that we don’t support “fork”. Most of the
daemonization libraries for MRI fork the process and then terminate,
leaving the forked child to run headless. It’s simply not possible to
support fork on JRuby, since the JVM spins up lots of threads and
signal handlers that don’t migrate to the child process. So what can
we do?

Well if you are able to have the child process start up anew, you may
be able to use my Spoon gem or the posix_spawn C call it leverages.

Here’s an example of launching JRuby in daemon mode using Spoon:

require ‘rubygems’
require ‘spoon’

Spoon.spawnp ‘jruby’, *ARGV

Of course this is a trivial example, which doesn’t even attempt to
pass along -J flags to JRuby or Ruby flags like -v and -w, but you get
the idea. What happens here is that Spoon.spawnp uses posix_spawnp to
launch “jruby” from PATH with the specified arguments. posix_spawn and
posix_spawnp are not standard POSIX functions, but they are supported
by basically all the major Unix variants:


Spoon also includes an example (directly in lib/spoon.rb) that shows
the potential:

pid = Spoon.spawn(‘/usr/bin/vim’)


This launches vim as a child process, but avoids all the terminal
breakage that normally comes from JRuby launching a tty-sensitive
subprocess. The sub-vim works perfectly.

posix_spawn is what Wayne M. describes as “fork/exec on
steroids”. It provides just about every combination of security, IO,
and subprocess wrangling you might expect to do in a typical fork/exec
scenario without actually using fork/exec. It also does it in one
shot, avoiding issues like those I mention in my blog post about
fork/exec on JRuby:

Anyway, have fun with Spoon and posix_spawn :slight_smile:

  • Charlie

To unsubscribe from this list, please visit: