Charles Engelke's Blog

May 4, 2009

RailsConf 2009 Tutorial – jRuby on Rails

Filed under: Uncategorized — Charles Engelke @ 12:06 pm
Tags: , ,

I’m starting this year’s RailsConf with a tutorial on jRuby on Rails.  I’ve fiddled with it a few times, and I have the distinct impression that it’s a more stable production platform than the regular Ruby interpreter.  But there are a few issues I’ve had.  I hope today’s tutorial will help me resolve them.

I’m not much of a note taker, so this (and other posts this week) will probably be pretty thin, with just reminders of core information tidbits I glean here.

The speaker is Nick Sieger of Sun Microsystems, and he’s put his slide desk online at his blog.  The link to the actual slides isn’t there (yet), so I won’t put it here, either.  It looks like he’ll probably soon put up a post with the link.

The talk is going to start from absolute zero.  Since I’ve actually installed and used jRuby (very casually) there will be some familiar stuff for me at first.

Download GlassFish, a Java application server we’ll be using.

Download jRuby, too (this is the latest production version as of today).

You’ll need the real JDK, too.

Install the JDK.  Add its bin subdirectory to your path, and set an environment variable named JAVA_HOME to the root of the JDK install.  Test it by running “java -version”.

Install jRuby by unpacking it anywhere you want.  Add its bin subdirectory to your path (he emphasizes adding it to the end of the path).  Test it by running “jruby -v”.  Run irb or other Ruby tools by prefixing them with “jruby -S”, as in “jruby -S irb”.

Run jRuby with the Java “server” VM with “jruby –server”.  That’s better overall performance, at the cost of slower startup.  You can pass a variety of Java arguments to the JVM with “jruby -J<argument>”.

Oh, you want jRuby at the end of the path so that its utilities don’t run when you want the regular Ruby ones.  So “rake” gives the regular Ruby rake, “jruby -S rake” gives the jRuby one.

jRuby has all the standard 1.8.6 Ruby things – the libraries, RubyGems, Rake, RSpec.  It’s also integrated with the Java libraries.  Go into jRuby’s irb, and type

java.lang.System.out.println “Verbose Hello”

It works!  Not that you’d want to do that, but I’m sure I’m going to want to use the Java cryptographic tools.

Install a bunch of needed gems (I had to be in a command shell with administrative privilege to do this in Windows 7):

jruby -S gem install rails mongrel jruby-openssl

Now, just create a Rails application with “jruby -S rails appname”.

Install ActiveRecord-JDBC or MySql or SQLite3 (or both):

jruby -S gem install activerecord-jdbcmysql-adapter
jruby -S gem install activerecord-jdbcsqlite3-adapter

Now fix your Rails application’s database.yml to point to the JDBC version of the appropriate database adapter.  For example, “adapter: jdbcsqlite3”.

Now here’s a trick I could have used (and will be using)!  Use embedded Ruby to have a single configuration file work for both jRuby and MRI.  Put this in database.yml:

<% jdbc = defined?(JRUBY_VERSION) ? ‘jdbc’ : ” %>
adapter: <%= jdbc %>mysql

[I just noticed that WordPress is “fixing” my single and double quote marks, even in code.  It’s easier for me to tell you figure out that they’re really all straight quotes than to figure out how to get them in WordPress right now.]

And now create a Rails application in the regular ways.  Just remember to use “jruby” instead of “ruby”, and to prefix other commands (like rake) with “jruby -S”.

Found a bug (in jRuby? in Rails? hard to say, but probably either in Rake, or in a Rails Rake task): if your Rails application’s environment.rb specifies needed gems, you can usually install them with:

rake gems:install

But, if you use:

jruby -S rake gems:install

it says it works, but it doesn’t (“jruby -S gem list” doesn’t show them).  It appears that it installs these gems under MRI instead of under jRuby.  Of course, you can just manually install each needed gem with “jruby gem install”.  It’s just the Rake task that gets derailed.  Note that this happened under Rails 2.2.2, which is what our existing application under development is currently using.  I haven’t checked to see if it still happens in Rails 2.2.3 (the current version as of today).

You can speed up Mongrel under jRuby by removing the mutex it no longer needs.  You have to edit Mongrel’s source to do this.  Look for the block starting “@guard.synchronize” and comment it out.  You have to also set “config.threadsafe!” in your application’s appropriate environment file to have this help (or change it globally for Rails under jRuby by editing lib/initializer.rb there.

The speaker’s JRuby-Rack gem allows you to run any Rack-based application (like Rails) under any Java Servlet API server.  That sounds promising for production use.  I’ve got to learn a lot more about the Java server ecosystem to take advantage of it.

The talk is now really turning to ways an experienced Java shop can run Ruby on Rails well in their infrastructure.  There’s a lot of background I don’t have, so this can point me to the right place to start, but I can’t understand it well enough to use it as a result of this talk.

Lots of talk on Warbler – I don’t have the context to understand it now (or know why I should care).

Google App Engine with jRuby.  Now, this interests me.  There’s going to be hackfest on Wednesday night at CabooseConf (a side meeting to RailsConf) that I’m going to want to visit.  Of course, Java support on Google App Engine is very preliminary, and there are lots of restrictions.  But the speaker says that jRuby on Rails works!  Well, except for a few minor issues like no ActiveRecord.  Not real practical yet.  But very encouraging.  There’s a talk at 11:45 AM this Wednesday that goes into more details.

[Side note: I’ve been trying to get our current development application running here in different configurations, and found I couldn’t get it to run under MRI using MySql (jRuby with MySql, or either with SQLite3 worked fine).  This isn’t related to the talk, but I found the solution on Google.  If you’re running a 64 bit version of Windows, you either need to be running MySql 5.0.x instead of 5.1.x, or else get the libmysql.dll file from an older version of MySql and put it in your Ruby’s bin subdirectory.  I don’t want to forget that the next time I wipe and reinstall everything on my laptop, hence this note.  It would be really nice if the precompiled gem for MySql gets fixed to avoid this problem, but I’ve noticed that the Windows platform is often not given much attention in the Ruby and Rails communities, so I’m not holding my breath.]

The tutorial has hit a real lull for me.  The Java ecosystem is incredibly rich, and layered upon layers.  It’s very hard for an outsider like me to keep track of the 27 billion different kinds of tools out there, and we’ve been talking for about an hour about those.  From the perspective of a Ruby person wanting to leverage some of that Java stuff, well… yawn.

We’re wrapping up now.  There was a lot of value to me in the first half of the talk, but not in the second half.  And I don’t think it’s just me.  It seems like the speaker got really bogged down at this point.  Overall, worthwhile, but it could have been even better.

Blog at