Skip to main content

Writing a Unix daemon in Java with Akuma

Posted by kohsuke on January 31, 2009 at 11:40 AM PST

As explained in here, writing a proper daemon requires various function calls that are traditionally only available to native applications. So typically, Java applications rely on external wrappers like Apache commons daemon or Java service wrapper, or even worse, just ignore those conventions and do Runtime.exec.

But this creates an unnecessary inconsistency between how you launch a program in the foreground vs how you launch a program in the background, and hurt the user/administration experience.

To solve this problem, Akuma is provided as a library that can be embedded in your application. After your program starts normally, you can programmaticaly decide whether you want to launch into the background (which could be driven by your application-specific command line switch or something) then call into Akuma to initiate the daemonization.

Behind the scene, Akuma will figure out the exact command line options given to the current process, then use fork/exec combo plus some additional steps to start a daemon. Unlike a real Unix daemon, Java has to call exec after fork, because the forked JVM loses GC threads and HotSpot compiler threads. However, the use of fork/exec allows Akuma to do some interesting things that can never be possible with Runtime.exec, which I'll discuss later.

Head over to the project website for more details and downloads. Currently it supports Linux, Solaris, and Mac OS X. In theory this should also work on FreeBSD, but haven't been tested.

Related Topics >>

Comments

I use nohup to prevent the process from getting killed!

Except shell will kill you before it exits. That said, I think you are technically correct, that if you do "kill -9" your shell, then the child process will be adopted by init. Still, that is not the way you want to start a daemon :-)

I thought orphan processes are adopted by init, so ppid will be 1 after you kill the shell.

robc -- in fact I wonder if one could embed JVM in a kernel as a module. Not that I have any use for it, but it could be fun.

comrad -- "server &", wouldn't detach your process from a shell, so if you kill your shell, it'll be gone. There are other problems such as preventing the current directory from being unmounted, umask that can be incorrect, etc.

What does it better than ./server & ?

I'm eagerly awaiting a blog post titled "Writing a Unix kernel in Java with Kakushin". :-)

Another project? How many so far? :-)

This is intended to be a part of Hudson, so I'm using the MIT license. I added the license info to POM and redeployed the Maven site. I believe MIT license is compatible with ASL.

And yes, we should be able to do setuid. I just added them in the signature.

Looks great, what's the licensing? *hoping for something ASL 2.0 compliant* Would a library like this be able to support setuid, that is, the process giving up root access so that a Java application could bind to privileged ports in a safe way?

This one started as a lunch time conversation with my usual lunch buddies. We were talking about how painful it is for people with scripting background to embrace Java-based container, and it reminded me of issues that Hudson had with SMF of Solaris and the additional dependency I had to have for a Debian package.

So in a big picture, it's all inter-connected in my mind.

And since you mentioned about "another project" :-), I should mention that I already wrote one more project (http://github.com/kohsuke/transienttmp/tree/master) since then!