saush

JRuby on Rails running in Apache Tomcat

Posted in java, JRuby, Rails, Ruby by sausheong on June 5, 2007

I tried JRuby for the first time in small project listed in my previous blog entry. While I wouldn’t say it’s love at first sight (or first use), it intrigued me sufficiently to try out other usages of JRuby.

What is JRuby? If you just think it this way — the Ruby that you and I know and love is a C implementation of the Ruby programming language — then JRuby is quite easy to understand. JRuby is the Java implementation of the Ruby programming language.

What the major difference and advantage in JRuby is that you’ll be able to define and interact with Java classes in Ruby directly. And that’s it. It’s not really different from Ruby, except that some built-in classes are not supported. And if you look at it from another angle, it’s not really that different between doing it this way (using JRuby) and using WIN32API or WIN32OLE, except of course you’ll need to know all the Java nuances and quirks.

Enter JRuby on Rails. Why JRuby on Rails? I think anyone who has done Java and Rails would be able to answer this one. It’s simply the vast ocean of Java libraries available, both good and bad, that gives JRuby on Rails the appeal for me. No doubt, the ‘enterprise’ factor of Java EE (i.e. running on a Java EE app server like Glassfish or the likes) is pretty appealing to those who care but I would say it’s not really worth it (at least at this point in time).

I was quite impressed with the demos done with JRuby and Glassfishv2 during JavaOne so I thought to give it a run to see what happens. The results are not too bad, although not everything works smoothly. For the current status of Rails support in JRuby click here.

Let me run through quickly how you can deploy a JRuby on Rails application on Apache Tomcat 6. Why Tomcat? While there are a growing number of Java EE application servers out there, Tomcat is probably the one that most Java EE programmers cut their teeth and is most familiar with.

1. You’ll need to install JRuby. Installation is quite easy, just download the latest package from http://dist.codehaus.org/jruby/ and then unzip it into any directory.
2. Now set the environment variable JRUBY_HOME to point to this directory and set your path to point to JRUBY_HOME/bin. If you’re doing this all the time you should set this permanently.
3. Now quickly test your JRuby installation by typing ‘jirb’ on your console and then the following:

$ jirb
irb(main):001:0> require 'java'
irb(main):002:0> frame = javax.swing.JFrame.new "JRuby Frame"
irb(main):003:0> frame.add "Center", button
irb(main):004:0> frame.setVisible true
irb(main):004:0> frame.setSize 200,100

4. You’ll notice that the frame is resized dynamically
5. Now you’ll need to install the Rails gems. Go to JRUBY_HOME/bin and run this command:

$ jruby gem install rails

JRuby will automatically install the necessary rails gems.

6. You’ll need to install the ActiveRecord-JDBC gem as well

$ jruby gem install activerecord-jdbc

7. Now, you can create or take your existing rails application and add the Rails-Integration plugin.

$ rails JRubyRailsTest
$ cd JRubyRailsTest
$ script/plugin install svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike

8. Check the rake tasks available now, you should have a couple of new rake tasks that starts with war:

$ rake –tasks
...
rake tmp:war:clear             # Clears all files used in the creation of a war
rake war:shared:create         # Create a war for use on a Java server where JRuby is available
rake war:standalone:create     # Create a self-contained Java war
rake war:standalone:run        # Run the webapp in Jetty

The tasks are pretty self explanatory.

9. There are a couple of things you need to change in the Rails configuration itself to enable Rails to run properly under a Java EE application server so you need to go into the config directory now.
10. Open up environment.rb and add these couple of lines in :

if RUBY_PLATFORM =~ /java/
  require 'rubygems'
  RAILS_CONNECTION_ADAPTERS = %w(jdbc)
end

This should come just before

Rails::Initializer.run do |config|

This will enable you to use ActiveRecord-JDBC. There are a couple of configurations given on other tutorials but this is the one that works for me.

11. Now open up database.yml to configure the database connection.

development:adapter: jdbc
 driver: com.mysql.jdbc.Driver
 url: jdbc:mysql://localhost:3306/<myDevelopmentDatabase>
 username: <username>
 password: <password>

production:
 adapter: jdbc
 driver: com.mysql.jdbc.Driver
 url: jdbc:mysql://localhost:3306/<myProductionDatabase>
 username: <username>
 password: <password>

Remember to change both the development and production. You can point them to the same database, but right now, the Rails-Integration will redirect to the production database once you archive your application into a WAR. In this example, I’m using MySQL but you can use any JDBC URL to connect to any JDBC enabled database.

12. If you’re doing a new application, and you want to generate some code, remember to use JRuby and not the normal Ruby interpreter. For example, to create a scaffold for User (assuming you have done all the necessary table creation in your database of choice)

$ jruby script/generate scaffold User

If you can’t generate, go back and check out steps 9 – 11. Also to note is that you’re running Java as well, so check your classpath if you are missing the JDBC drivers for your database.

13. For instant gratification, run WEBrick on JRuby:

$ jruby script/server

And try it out quickly to ensure it works.

14. Onwards to make it work for a Java EE application server! First, you’ll need to add in any libraries you need into the Rails-Integration configuration, so that it’ll include that library when it builds the WAR file. Go to <your Rails application>/vendor/plugins/goldspike/lib/war_config.rb and add in your libraries. For example, to use MySQL, you’ll need to put in the MySQL drivers like this:

add_library(maven_library ('mysql', 'mysql-connector-java', '5.0.4'))

Browse around the code until you find a place to put this line.

15. We’re almost there. Run the rake task in your Rails application folder to create the WAR file:

$ JRUBY_HOME/bin/jruby JRUBY_HOME/bin/rake war:standalone:create

This will create the WAR file by archiving your code and any libraries needed to run JRuby. The first time you run it might take a while and you’ll need to be connected to the Internet in order for Maven to bring in the Java libraries from its public repository but subsequently it’ll be much faster. A problem I faced earlier on is that while getting some libraries, the connection will expire and creation is aborted. I had to run it a few times before it completes properly.

16. You’re done! You now have a WAR file that wil run on Tomcat 6 or Glassfishv2 (I tried both). Just deploy them normally as you would any web application.

About these ads

11 Responses

Subscribe to comments with RSS.

  1. Sam said, on June 23, 2007 at 12:18 am

    Thanks for the walk through. As a java guy looking into rails, this is very exciting. I’m going to try this out in the next day or two and I’ll let you know how it goes.

  2. sausheong said, on June 23, 2007 at 12:27 am

    You’re welcome. There’re not that much literature out there on JRuby yet, but with the popularity of Ruby and Java, JRuby on Rails should become pretty hot in the coming months/years.

  3. Peter Marreck said, on June 23, 2007 at 3:02 am

    You missed a tidbit in the Swing part of your tutorial- “button” is not defined, which I fixed by adding the following line: >>button = javax.swing.JButton.new “Center”

  4. sausheong said, on June 23, 2007 at 11:10 am

    Yes, you’re absolutely right. Thks for the correction!

  5. Nick said, on June 27, 2007 at 10:29 pm

    `vendor/plugins/goldspike/lib/war_config.rb` should be `config/war.rb`. See http://headius.com/jrubywiki/index.php/Rails_Integration for details.

  6. sausheong said, on June 27, 2007 at 10:45 pm

    Hi Nick, I didn’t go try to change war.rb, changing war_config.rb worked for me. I didn’t read the page u sent here until now, that is probably the correct way to go. Thanks for the tip!

  7. Kyle Wendling said, on July 31, 2007 at 11:16 am

    Just a heads up.
    I got stuck here:

    $ rake war:standalone:create

    On almost any system with rake already installed this will break, it’ll complain about not finding JDBC. This cmd will run the original Ruby rake and not the JRuby version. I made symlinks from the rake in the JRuby to jrake, and ran:

    $ jrake war:standalone:create

    and it worked fine.

  8. Kyle Wendling said, on July 31, 2007 at 2:13 pm

    if RUBY_PLATFORM =~ /java/require ‘rubygems’
    RAILS_CONNECTION_ADAPTERS = %w(jdbc)
    end

    should be:

    if RUBY_PLATFORM =~ /java/
    require ‘rubygems’
    RAILS_CONNECTION_ADAPTERS = %w(jdbc)
    end

  9. Kyle Wendling said, on July 31, 2007 at 2:13 pm

    $ rails JRubyRailsTest$ cd JRubyRailsTest
    $ script/plugin install svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike

    should be:
    $ rails JRubyRailsTest
    $ cd JRubyRailsTest
    $ script/plugin install svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike

  10. sausheong said, on July 31, 2007 at 3:10 pm

    Thanks for the tips Kyle!

  11. Mauro said, on April 6, 2009 at 11:42 pm

    it doens’t work for me, any help?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 444 other followers

%d bloggers like this: