Wednesday, May 13, 2009

JRuby Nailgun Support in 1.3.0

I've merged changes into master (to be 1.3 soon) that should make Nailgun easier to use. And 1.3 will be the first release to include all NG stuff in the binary dist.
  • jruby --ng-server starts up a server. You can manage it however you like
  • jruby --ng uses the Nailgun client instead of launching a new JVM for the command you run. You'll just need to run make in tool/nailgun to build the ng executable (already built for you on Windows).
Future improvements will include having --ng start up the server for you if you haven't started it, passing signals through (don't expect signals to work at all right now), better management of threads and commands, and so on. But it's a good start, and people can try to play with it and report issues more easily now.

Heres a sample session:
~/projects/jruby ➔ cd tool/nailgun/ ; make ; cd -
Building ng client. To build a Windows binary, type 'make ng.exe'
gcc -Wall -pedantic -s -O3 -o ng src/c/ng.c
ld warning: option -s is obsolete and being ignored

~/projects/jruby ➔ jruby --ng-server
NGServer started on all interfaces, port 2113.
[1]+ Stopped jruby --ng-server

~/projects/jruby ➔ bg
[1]+ jruby --ng-server &

~/projects/jruby ➔ jruby --ng -e "puts 1"

~/projects/jruby ➔ time jruby -e "puts 1"

real 0m0.609s
user 0m0.482s
sys 0m0.119s

~/projects/jruby ➔ time jruby --ng -e "puts 1"

real 0m0.073s
user 0m0.010s
sys 0m0.018s

Update: For those not familiar, "NailGun is a client, protocol, and server for running Java programs from the command line without incurring the JVM startup overhead. Programs run in the server (implemented in java), triggered by the client (written in C), which handles all I/O."

Update 2: It's been brought to my attention that we no longer ship a pre-configured Makefile for the ng client, so your build command line should actually look like:
~/projects/jruby ➔ cd tool/nailgun/ ; ./configure ; make ; cd -
Alternatively, you can run "ant build-ng" in the JRuby root, which will do largely the same thing for you using Ant.


  1. For comparison when not using NG:
    $ time jruby -e "puts 1"

    real 0m5.357s
    user 0m0.504s
    sys 0m0.191s
    That's a huge difference, and it should make JRuby web app deployments much better.

    Thanks guys!

    - Matt

  2. I'm still dreaming of someone to build a comprehensive Java command line toolkit.

    Nailgun, a fixed version of JLine, a reasonable command line options parser (all the ones out there are unmaintained and/or crap...).

  3. Martin: I'm an admin on Jline now, so if there's fixes you think need to get in jump on the ML and say so. We can put out a release.

  4. Are there any known input/stdin problems? I can't get irb to run appropriately.

  5. Mernen: Yes, it appears that jirb does not work at the moment. We'll have to track down exactly what's wrong with it. When I try it, I see it launching stty (part of JRuby startup I think) and never getting any further...

    Can you file a bug for it please?

  6. Charles: that is very good news that JLine is maintained again. I'll file some bugs with SourceForge if you don't mind.

    About the blocking stty call: I guess I ran into that bug here, too. The issue (at least the one I had) is that JLine is calling stty when initializing a terminal.

    Now the issue is that in your nailgun setup, or in the case where you pipe input to a command ("cat foo | jruby --ng"), the input stream is not really terminal, and stty thus blocks. I can't quite find the correct man pages etc now, but I think that was the issue. On some UNICes (Linux in particular if I remember correctly), it is possible to give stty a parameter telling it not to block, but I can't quite find the reference.

  7. Hi Charles,
    I tried your suggestion. This time it is a different PC (Earlier I tried work PC, this time it is my dell laptop at home) I created a blank rails app through netbeans. Then got back to command line and repeated the experiment but this time I timed the complete wall time as you have suggested

    But in the end there is still a huge difference in performance. Plain jruby seem to run circles around nailgun.

    Jruby starts it in 10 seconds. And nailgun takes about a minute. After running ng ten times ng there is no big difference in the time taken.

    with ng after about 10 runs....

    C:\ngtest\RailsApplication1>jruby --ng -e 'puts; require "config/environment";puts'
    Sat Jul 03 00:07:40 +0100 2010
    Sat Jul 03 00:08:33 +0100 2010

    Now without ng we get..

    C:\ngtest\RailsApplication1>jruby -e 'puts; require "config/environment";puts'
    Sat Jul 03 00:09:29 +0100 2010
    Sat Jul 03 00:09:38 +0100 2010

    So looks like I have hit a bug. Can you post the url for filing bugs please?

  8. Thanks for your help Charles. Just filed a bug!