Monday, April 23, 2007

Rails in Jetty--deployment as a simple war file

In previous posts (here, here and here) I blogged about deployment of Rails in various ways with a Java developer focus. Some time ago I started looking at JRuby again and thought about deployment of Rails on the JVM as a neat idea.

In this post, I will first show how easily this is accomplished. Then, I will write a bit about the perspectives of this for a Java developer. Because this is cool in many ways.

Creating the war
Today, I got around to trying it out for real. I took a real application of mine written in Rails and deployed it as a standalone war. Hugh! How is that done? Easily, just follow the instructions here at the JRuby wiki. Here are the steps I needed to perform (in short form):
  • Installed the Rails-Integration plugin
  • Installed the ActiveRecord-JDBC gem
  • Added mysql driver jar dependency
  • Added RedCloth gem dependency (my application uses RedCloth)
  • Modified config/database.yml to reflect ActiveRecord-JDBC setup for production env
I then simply ran "rake war:standalone:create" and a standalone war file was build for me. A quick look into the war shows me that it packages:
  • The rails application structure
  • The mysql jar in lib
  • The jruby-complete.jar file
  • The jruby "platform", including the jruby bin and lib dirs (and gems)
I then typed "rake war:standalone:run" and jetty was downloaded for me, started and the warfile deployed. No pain, just works.

What is nice about this?
One important benefit is obvious. In many places, the barrier to entry into dynamic languages like Ruby and its frameworks like Rails, is set not only by the developers, but also by the part of the business that performs the deployment and systems management. When you can simply drop a warfile to systems management, there are no questions asked. All built up knowledge can be reused there.

Second, it is nice again to be able to perform a self-contained deployment unit in a single file. As you might have read above, my Rails application is using RedCloth, which must exist as a gem on the Ruby installation it is deployed on. With the war, I can make it a packaged dependency.

Third, we are back in one process and multiple threads, which we in Java land has come to love. It is more lightweight to the operating system and it is easier to monitor. The Rails-Integration in war deployment automatically instantiates multiple JRuby runtimes to overcome the problem of Rails not being thread-safe.

And fourth, Sun is working on introducing a new "invokedynamic" bytecode to better support dynamic languages. If this gets implemented (I think it is planned for Java 7), JRuby on the JVM might perform better than MRI.

I am so excited!

2 comments:

Anonymous said...

Can I take this war file and deploy it within Tomcat or Glassfish now? Do I need any extra configuration?

Per Olesen said...

Absolutely!

Well, I have not actually tried deploying in anything else than jetty. But jetty is "just" a servlet container like tomcat.

So yes, you can. Nice hugh!? :-)