Feb 25, 2009

JRuby on Rails and Development Efficiency

I've been working with JRuby for about six months now, and it has been pretty good. It has native thread support, and you have a number of different options available from the Java world.

As a deployment strategy, JRuby is pretty solid IMO. However from a development perspective it is a bit slower than MRI. The biggest one you notice is that JRuby takes a while for the JVM to warm up. This is fine if you're just running Mongrel or WEBrick or something, but when you have a bunch of small scripts or Rake tasks to run or something to play around with in irb, it is quite annoying to have to use JRuby and wait that extra few seconds for the JVM to load. Also for some reason it takes way longer for my test suite to run in JRuby than with MRI. Oh well, whatever.

Another problem is that many gems are native, and therefore not available to JRuby. At this point JRuby has enough of a following for popular gems to have a JRuby port somewhere, but the matter of finding it and getting it to work on all your developers' machines is a pain in the ass. Better to just do it once on the deployment machine(s) and be done with it. Some examples of gems that don't work in JRuby: rcov, RMagick, mysql, anything to do with datamapper. The memcache-client gem used to work, if you use version 1.5.0 it works fine but the latest one fails.
EDIT: There's been a bit of confusion by what I meant here. What I mean is that the gems in the repository do not work with JRuby, so going 'jgem install GEM' does not work, you have to find the port online. This isn't usually that difficult, but a bit more time-consuming than the standard way of doing things.

However I'd say JRuby is great for production for a few reasons. First off, it has access to native threads. I believe Ruby 1.9 uses native threads, but my Rails app currently does not work with the Ruby 1.9 available in the Ubuntu repositories and I'd rather not have to maintain a new Ruby install unless absolutely necessary.
JRuby also has access to a wider range of application servers. Mongrel works well with JRuby, and any other web server written in Ruby should work fine as well. JRuby can also be deployed as a WAR with any application server that uses WAR files. We're using Glassfish, but I think you can do it with Tomcat and others too.
Finally, JRuby has access to Java libraries. Say what you will about Java the language, there are a ton of Java libraries out there. For basic stuff, Ruby has pretty much everything it needs, but when you want to move outside of web development things get sparse quickly. Want to write an OpenOffice plugin? JRuby can do it by using OpenOffice's Java API. Want to use a NLP tool like GATE? The API is in Java. Where are things like this for Ruby?

Anyway, IMO ideal setup is:
development - Ruby, unless you're using some Java libraries like I mentioned above
production - JRuby
This may change as Ruby 1.9 gets better, but at the moment I'm liking the above setup.


sundog said...

I'm doing exactly the same thing. MRI Ruby/Mongrel in Cygwin in Windows for development and JRuby in a WAR file in Tomcat for Production.

fiddlerBrad said...

What's this about "rspec won't run in jruby"? Rspec _comes_ with Jruby since about 1.1. You need to check more sources, there are a lot of things that have been hooked up, especially since the benchmarks showed Jruby to be 2.5-3 times faster than MRI (until 1.9 came out).

Rob Britton said...

@fiddlerBrad: I'll have to rephrase. What I meant to say is that these gems don't work by going 'jgem install gemname'.
Rspec comes with JRuby? Not that I'm aware of. I had to manually install the gem from source with JRuby 1.1.6.

And no, JRuby is not 2.5-3 times faster than MRI. The benchmarks you might find by googling may say so, but I work with both every day and for a more complex web app, JRuby is definitely not 2.5-3 times faster, in fact in many cases even after the JVM warms up JRuby runs 2.5-3 times slower than MRI, at least based on the profiling I've done with my application.

Rob Britton said...

@fiddlerBrad: Ah, I see rspec there now. My mistake, thanks!

dkubb said...

I'm the maintainer of DataMapper, and I'm not sure what problems you had installing it, but I can confirm all of its specs should pass with JRuby. They even pass with MRI 1.9.1, and JRuby in --1.9 mode.

We've been testing each gem release against JRuby and 1.9 for at least the last month. If you are having problems with it please report it to me directly, or on irc/freenode (I'm dkubb) or file a ticket at http://is.gd/aa86. To my knowledge there are no outstanding JRuby related tickets.

You may be having problems using one of the 3 RDBMS based adapters, which rely on drivers from the DataObjects project. Those drivers we originally written for MRI 1.8 / 1.9 and haven't been ported to JRuby yet -- although there is some work being done on this (more help is probably needed though).

Altogether there's about 25-30 adapters for DataMapper, and I only know of 4 that are based on MRI-only libraries, so DM should work fine with JRuby. Granted, the RDBMS adapters are probably the ones in the most demand, but there's even a dm-jdbc-adapter available, although I haven't personally tested it yet.