Archive for November, 2006|Monthly archive page

First JRuby Impressions

jrubyI’ve had my first taste of JRuby this week-end, I wanted to see if I could get Raven running on it and how easy (or hard) that would be. My first impression was very positive. The distribution is definitely nicely built, including all the necessary script to run a jirb (the JRuby equivalent of irb) session or run RubyGems install in no time. Installing Rake and Raven was a 5mn deal. I’ve had a little surprise the first time I ran Rake though, if you run it from the bin directory, you’ll end up in an infinite loop (load ‘rake’ will load the rake script instead of the gem, which results in the script calling itself).

Then I got into trying to have Raven running on JRuby and that required far more time. Here are all the problems I ran into, successively:

  • The Net::HTTP constructor will complain if you give a string for the port instead of an int (matz interpreter doesn’t care either way).
  • The Kernel.Integer() method normally throws an error when what you’re passing isn’t an integer, JRuby returns 0.
  • If you do a raise, “Too many artifacts”, what will be effectively passed to the exception constructor by JRuby is the “Too many artifacts” string, and not the artifacts object. Weird bug.
  • In matz Ruby, doing a compare like [1,6,1] <=> [] will return 1. JRuby always considers the size first and will return -1 (who said that size didn’t matter). This one actually took me quite some time to spot as it was deeply hidden.
  • The operator == isn’t redefined on Process::Status so you can’t do $? == 0 to test that a process executed successfully. You’ll have to do $?.exitstatus == 0.
  • The method ctime doesn’t exist on File::Stat, that’s a bit annoying as I couldn’t find any replacement.

Altogether it’s only small problems and details but the real problem is more the accumulation. Raven’s codebase isn’t large at all and that’s a lot of fixes or even hacks to do. That being said, I’ve been able to run Raven after a few hours of work, which is still pretty good. Beside I didn’t expect to have Raven running right away, I can’t even imagine what a nightmare it must be to implement the whole (and large) Ruby API in every single details!

What is a bit more annoying is the startup time. And that I can;t change as it has not much to do with JRuby but much more with the Java VM. Pure execution is slightly (I’d say about 30 to 40%) slower but still reasonable. However a build system is used for many short running sessions and I’m afraid the quite long startup will impact Raven users pretty badly. Especially when you compare it to the immediate response of the matz interpreter.

I can’t wait for a fork of the now GPL’ed Java VM to happen to make it more suitable for that kind of application!


Cerberus: Continuously Test in Ruby

Just came across this nice software on RubyForge while I was looking for some Continuous Integration solution for Ruby and more specifically Rake. Check out the web site and this post about Cerberus. Looks promising and could be a good match for Raven.

Raven 1.1: Building More Java with Ruby

Building Java with RubyI’ve just released Raven 1.1 and I’m pretty happy with the new features. For the newcomers Raven is a build system that leverages Ruby tools (namely Rake and Gem) to let you build Java projects easily. It provides a way to handle dependencies, specific Rake tasks for Java and it’s Ruby scripting!

So this latest release lets you install all the dependencies you need directly from the command line. You can install either a single dependency, several dependencies or a whole group. You can also specify the exact version you want or let Raven find the latest one. The package search is based on indexes stored on Raven’s Rubyforge site. These are downloaded (but only if they’ve changed) and the right packages are selected from your search parameters. Then it automatically goes to the Maven repository the artifact comes from, downloads it, wrap it in a Gem and installs it in the Ravem Gem repository. And you’re set!

So it’s as simple as:

raven install httpclient
raven install -g xstream xstream:1.2
raven install –all -g axis2

Neat? Then you can easily write your Rake script to use these dependencies and build your java project using Raven’s java tasks. See my previous post about this.

I have tons of ideas for the next releases, like support for code generation tools (mostly XDoclet and XMLBeans) or making multi-project builds even easier. Something else you’d be interested in?