Setting up a local SDS to run under JRuby

JRuby and the SDS

This guide assumes that you already have a successful installation of the Development SDS installed locally. If you don't, please follow these directions. Actually those instructions need to be updated because you don't need to install most of the Gems anymore the SDS includes frozen versions of them in it's vendor/gems directory when you checkout the code.

The basics of getting an existing SDS instance using MySQL to run under JRuby are:

  1. Install the JRuby environment
  2. Install the required gems under the JRuby environment
  3. Change your database config to use jdbc

Table of Contents

Installing JRuby

The JRuby Wiki is full of useful information.

As of March 9 2008 the JRuby team is just about to release JRuby 1.1 RC3. This is expected to be the last release candidate before v1.1 final is released. Until JRuby 1.1 is released however checkout trunk JRuby from source and build it yourself (see below).

Installing JRuby from source

You will need Java 1.5 or 1.6 and Ant 1.6 or higher to compile JRuby. JRuby runs fine with both Java 1.5 and 1.6 but it s faster on Java 1.6.

First decide where you will install JRuby. I recommend installing it in a development directory in your home folder. Assuming you are in the directory where you would like JRuby to be installed:

svn co http://svn.codehaus.org/jruby/trunk/jruby
cd jruby
ant
ant jar-complete
ant create-apidocs

You can follow the install directions on http://wiki.jruby.org/wiki/Getting_Started#Downloading_Source_and_Building_Yourself

If you install JRuby into /usr/local/jruby you will most likely need to prefix any statements that write into this directory tree with sudo.

The ant task create-apidocs generates the javadoc for JRuby which you can find here: jruby/docs/api/index.html.

To update to the latest version of trunk JRuby:

svn up
ant clean
ant
ant jar-complete
ant create-apidocs

Dealing with multiple Ruby installations on one computer.

If you have already installed the SDS before this you already have a version of MRI Ruby installed (MRI stands for Matz Ruby Interpreter, matz is shorthand for the name of the creator of Ruby, Yukihiro Matsumoto, and MRI refers to the C version of Ruby).

It is perfectly practical to have a number of different installations of Ruby. Each one should have it's own home and location into which system extensions and Gems are installed. It is best not to change the Ruby that may have come installed with your OS but instead install updates or alternates into directories you have more complete control over.

While the Ruby that came with my Mac OS 10.4.x system is installed into /bin/ruby I have an up-to-date version of MRI Ruby (1.8.6_p111) installed into /usr/local/ruby. All the Gems I install are installed into a directory tree rooted at /usr/local/lib/ruby and I have symlinked /bin/ruby to point to /usr/local/ruby. This changes the way all program in my OS use Ruby and is pretty invasive. This works because:

  1. There are few (if any) OS services that rely specifically on the Ruby 1.8.2 that came installed on MacOS 10.4.x
  2. Ruby 1.8.6_p111 is a stable release and is very similar to Ruby 1.8.2

Updating the Ruby used by the system in MacOS 10.5.x is much more involved because Apple started supporting Ruby integration with the OS much more directly.

What is very safe and quite simple is installing alternate versions or platform types of Ruby into their own directories in a development folder you control that is separate from the OS system folders.

Aaron's methods

Aaron's suggestion below are so far limited to what you need to install the Gems need for the SDS in JRuby.

First, make sure you're using the jruby version of the gem command. I like to set up a uniquely named symlink to the jruby gem command:

cd /path/to/jruby/bin
ln -s gem gem-jruby

Note that when adding jruby to your path, make sure to add it to the end of your path, to avoid overriding any of the default ruby commands.

Stephen's methods

I do not normally use MRI and JRuby at the same time from the same shell.

When I am working in JRuby I cd to the dir where I have JRuby checked out and execute the following script to set the environmental variable $JRUBY_HOME and add the path $JRUBY_HOME/bin to the beginning of the environmental variable $PATH. This means that when I run a Ruby command like rake in that shell I will use the specific JRuby version of that rake command.

I also do not put JRuby in a system dir like /usr/local/jruby. Instead I have it checked out in my home directory.

This makes it easier for me to have a number of different JRuby installations which I can use for debugging or experimentation. Right now I have three different JRuby installations and a version of MRI Ruby 1.9. Each installation has it's own set of Ruby Gems (none of which overlap with the Gems installed for my MRI version of Ruby).

After cd'ing to a directory with a JRuby installation I execute the following to setup my environment:

$ . setpaths.sh

This is what the file setpaths.sh contains:

setpaths.sh
export JRUBY_HOME=`pwd`
export PATH=`pwd`/bin:$PATH
export JRUBY_OPTS=-rubygems

The shell command . is the same as the shell command source. This command executes the shell script in the current shell rather than spawning a sub-shell.

What the JRuby folks recommend

The JRuby folks in general recommend adding the path to the jruby/bin directory to the end of your $PATH environmental and then executing the JRuby specific versions of Ruby system commands like this:

jruby -S gem install RedCloth

And executing Ruby scripts that are not system commands like this:

jruby my_ruby_program.rb

In both cases executing jruby will setup the needed environmental variables. Using -S JRuby will run the JRuby-specific version of gem and the Gems will be installed into the proper location for Jruby. Use the form jruby -S command when you are running a Ruby command that is normally installed as a command line program when the language is installed or extended. Using this parameter tells JRuby to look in it's bin/ directory for the command.

The JRuby folks recommendation is the safest practice because if you always know to use jruby as the start of any command which should be executing in JRuby you won't have problems by inadvertently using MRI Ruby when you expected JRuby.

The rest of this guide assumes the use of the JRuby folks recommendations for integrating JRuby and MRI and running JRuby commands.

One of the few Ruby system commands that actually has a different name in JRuby is IRB, the Interactive Ruby console. In MRI ruby the command is irb in JRuby the command is jirb.

Installing the required gems

Currently the only required Gems (that are not included when you checkout the development SDS) to run the SDS are those needed to access databases and Hpricot. In addition the Gem rake is needed to run SDS Rake tasks.

The Gem activerecord-jdbc-adapter is needed to give ActiveRecord access to JDBC databases in general. There is also a specific Gem to install for each database you want to use. In addition there is also a specific Ruby driver for each database.

So to access MySQL with ActiveRecord in JRuby you need these Gems installed:

  • activerecord-jdbc-adapter
  • activerecord-jdbcmysql-adapter
  • jdbc-mysql

To access the Java database H2 you need:

  • activerecord-jdbc-adapter
  • activerecord-jdbch2-adapter
  • jdbc-h2

Installing the Rails and Mongrel Gems

First install the Gems Rails and Mongrel. Rails v2.0.2 is now included in the development SDS checkout by installing Rails will also install Rake and make further development easier. Mongrel is a higher performance http server than Webrick which is one included in the Ruby Standard Library.

$ jruby -S gem install rails mongrel
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed rake-0.8.1
Successfully installed activesupport-2.0.2
Successfully installed activerecord-2.0.2
Successfully installed actionpack-2.0.2
Successfully installed actionmailer-2.0.2
Successfully installed activeresource-2.0.2
Successfully installed rails-2.0.2
Successfully installed gem_plugin-0.2.3
Successfully installed mongrel-1.1.4-java
9 gems installed
Installing ri documentation for rake-0.8.1...
Installing ri documentation for activesupport-2.0.2...
Installing ri documentation for activerecord-2.0.2...
Installing ri documentation for actionpack-2.0.2...
Installing ri documentation for actionmailer-2.0.2...
Installing ri documentation for activeresource-2.0.2...
Installing ri documentation for gem_plugin-0.2.3...
Installing ri documentation for mongrel-1.1.4-java...
Installing RDoc documentation for rake-0.8.1...
Installing RDoc documentation for activesupport-2.0.2...
Installing RDoc documentation for activerecord-2.0.2...
Installing RDoc documentation for actionpack-2.0.2...
Installing RDoc documentation for actionmailer-2.0.2...
Installing RDoc documentation for activeresource-2.0.2...
Installing RDoc documentation for gem_plugin-0.2.3...
Installing RDoc documentation for mongrel-1.1.4-java...

Installing the ActiveRecord JDBC and Database Gems

Install the Ruby drivers for JDBC access to MySQL and H2.

$ jruby -S gem install jdbc-mysql jdbc-h2
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Successfully installed jdbc-mysql-5.0.4
Successfully installed jdbc-h2-1.0.63
2 gems installed
Installing ri documentation for jdbc-mysql-5.0.4...
Installing ri documentation for jdbc-h2-1.0.63...
Installing RDoc documentation for jdbc-mysql-5.0.4...
Installing RDoc documentation for jdbc-h2-1.0.63...

Now install the specific ActiveRecord adaptors for MySQL and H2 (the ActiveRecord JDBC adaptor will be installed automatically as a dependency).

$ jruby -S gem install activerecord-jdbcmysql-adapter activerecord-jdbch2-adapter
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Successfully installed activerecord-jdbc-adapter-0.7.2
Successfully installed activerecord-jdbcmysql-adapter-0.7.2
Successfully installed activerecord-jdbch2-adapter-0.7.2
3 gems installed
Installing ri documentation for activerecord-jdbc-adapter-0.7.2...
Installing ri documentation for activerecord-jdbcmysql-adapter-0.7.2...
Installing ri documentation for activerecord-jdbch2-adapter-0.7.2...
Installing RDoc documentation for activerecord-jdbc-adapter-0.7.2...
Installing RDoc documentation for activerecord-jdbcmysql-adapter-0.7.2...
Installing RDoc documentation for activerecord-jdbch2-adapter-0.7.2...

Installing the Warbler Gem for packaging a WAR

We also need the snapshot version (0.9.4) of the Warbler Gem. This is used to embed both JRuby, Rails, the Rails application and any needed Gems into a WAR file for deployment to a Java application server.

$ jruby -S gem install warbler --source http://caldersphere.net
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Bulk updating Gem source index for: http://caldersphere.net
Successfully installed warbler-0.9.4
1 gem installed
Installing ri documentation for warbler-0.9.4...
Installing RDoc documentation for warbler-0.9.4...

construct a WAR file from a Rails app.
The development SDS now comes with most of it's gems included right in the source code checkout in vendor/gems.

$ ls vendor/gems/
rubyzip-0.9.1
spreadsheet-excel-0.3.5.1
uuidtools-1.0.3

In addition it also now comes with version 2.02 of Rails unpacked into vendor/rails.

The SDS will use these specific Gems and version Rails regardless of what is or is not installed or updated in your JRuby installation.

Installing the Hpricot Gem

The required hpricot gem has native platform-specific code – in MRI when this Gem is installed a C library is compiled. The Java platform version includes a Java jar file. At this point there isn't a practical method to include both versions of Hpricot in the SDS code base and dynamically select which to use at runtime.

There are some updates that haven't yet been committed to the RubyForge repository for Hpricot so until the hpricot gem is updated you should download hpricot-0.6.159-java.gem and install it into the jruby gem library by hand.

curl http://www.telscenter.org/confluence/download/attachments/20236/hpricot-0.6.159-java.gem > hpricot-0.6.159-java.gem
jruby -S gem install hpricot-0.6.159-java.gem

After doing a manual install of Hpricot the file hpricot-0.6.159-java.gem is no longer needed. You might want to archive it somewhere.

Checking your local Gem installation

You can check to make sure everything is installed correctly by comparing the Gems you have installed to this list:

$ jruby -S gem list --local

*** LOCAL GEMS ***

actionmailer (2.0.2)
actionpack (2.0.2)
activerecord (2.0.2)
activerecord-jdbc-adapter (0.7.2)
activerecord-jdbch2-adapter (0.7.2)
activerecord-jdbcmysql-adapter (0.7.2)
activeresource (2.0.2)
activesupport (2.0.2)
gem_plugin (0.2.3)
hpricot (0.6.159)
jdbc-h2 (1.0.63)
jdbc-mysql (5.0.4)
mongrel (1.1.4)
rails (2.0.2)
rake (0.8.1)
sources (0.0.1)

Testing your JRuby install by building a simple Rails application

Try making a simple Rails app in JRuby. This will help you understand the difference between running JRuby system commands using jruby -S and running regular Ruby scripts using jruby without the -S parameter.

This is also a simpler application to use to figure out how to deploy a JRuby Rails app to a WAR.

Installing the Gem Rails added both rails and rake as command line programs. In JRuby these commands are installed in $JRUBY_HOME/bin.

  1. Create a new Rails application called blog and display a description of all the default rake tasks installed by Rails:
    jruby -S rails blog
    cd blog
    jruby -S rake -D
  2. Convert the database configuration in the blog app from the default that Rails sets up (SQLite3) to use H2:
    curl http://www.telscenter.org/confluence/download/attachments/20236/database_sample_h2.yml > config/database.yml
  3. Generate a scaffold for a simple model of blog comments. The Ruby code located at blog/script/generate will be executed by JRuby.
    jruby script/generate scaffold comment name:string body:text
  4. Run the database migration that was just created as part of the scaffold.
    jruby -S rake db:migrate
  5. Start your application on the Rails default port 3000 using Mongrel/
    jruby script/server

You should now have a very simple blog application running on port 3000.

Try it here: http://127.0.0.1:3000/

You should see the Rails Welcome Aboard page. Click on About your application's environment to see a description of the environment the blog app is running in.

The normal thing to do at this point is to delete public/index.html – this is the file that produces the Welcome Aboard page – and create your own page for the root of your site. This isn't necessary unless you want to extend this simple application.

I normally use http://localhost:3000/ rather than http://127.0.0.1:3000/ to reference my local sites. The only reason I suggested using http://127.0.0.1:3000/ above was because the JavaScript that executes in the Welcome Aboard page doesn't realize that localhost is a local reference when running in JRuby and it prevents the display of your environmental variables.

Try this page next: http://localhost:3000/comments and create at least two comments.

The Rails scaffold generated also included all the code for allowing RESTful access to the comments.

In Firefox try this: http://localhost:3000/comments.xml. You should see an xml representation of all the comments. You can look at any one comment like this: http://localhost:3000/comments/1.xml.

Edit the file app/controllers/comments_controller.rb and add the line: skip_before_filter :verify_authenticity_token near the top. It should now look like this:

comment_controllers.rb
class CommentsController < ApplicationController
  
  skip_before_filter :verify_authenticity_token

Rails 2.0 includes an AuthenticityToken when generating a form and expects this token to be present when HTTP POST, PUT, or DELETE requests are made. In this simple application this checking isn't needed. The line we just added turns of this check for the CommentsController.

After turning off the check for the AuthenticityToken you can create a new comment using curl to make a REST POST request like this (the curl command below works spread over two lines because the quote characters enclosing the data string also cover both lines):

curl -i -H 'Content-Type: application/xml' -X POST -d '<comment><name>third comment</name>
<body>This comment was created using a REST request with curl.</body></comment>' http://localhost:3000/comments

Here are the HTTP headers that are returned:

HTTP/1.1 302 Moved Temporarily
Connection: close
Date: Mon, 10 Mar 2008 17:36:13 GMT
Set-Cookie: _blog_session=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29 ... 503b1c89ed1; path=/
Content-Type: text/html; charset=utf-8
Server: Mongrel 1.1.4
Cache-Control: no-cache
Status: 302 Found
Location: http://localhost:3000/comments/2
X-Runtime: 0.05300
Content-Length: 98

Here's the html body that was returned:

<html><body>You are being <a href="http://localhost:3000/comments/2">redirected</a>.</body></html>

The Location header (as wells as the redirection in the html body) provides the url for the newly created comment: http://localhost:3000/comments/2.

Changing your SDS database configuration

Edit the config/database.yml file in the SDS application instance.

Using a MySQL Database

Change the database adapter to use the jdbc driver. The example below only shows changes to the production database connection. If you are doing development change the development database connection also.

The particular example below is setup so you can use appropriate adaptor to access the same MySQL database whether you are running in MRI Ruby or JRuby. This works because Rails evaluates this YAML configuration file first with ERB (the same default templating system Rails uses for views) before passing the result to the YAML parser.

From:

production:
  adapter: mysql
  database: sds_database
  username: username
  password: password
  host: localhost

To:

production:
  adapter: <% if RUBY_PLATFORM =~ /java/ %>jdbcmysql<% else %>mysql<% end %>
  database: sds_database
  username: username
  password: password
  host: localhost

Using an H2 Database

It is not possible to access H2 in the MRI version of Ruby so there is no advantage to using ERB templating to dynamically change the config depending on whether you are running in JRuby or MRI.

Instead your config/database.yml file should look like this:

development:
  adapter: jdbch2
  database: <%= RAILS_ROOT %>/db/sds_h2_database

production:
  adapter: jdbch2
  database: <%= RAILS_ROOT %>/db/sds_h2_database

H2 will save it's database in files based off the path supplied in value specified in database:.

If you are using H2 for the first time with this SDS instance you will first need to create the database and initialize the config_versions table:

Run the database migration to initialize the database:

jruby -S rake db:migrate

Execute this rake task to initialize the config_versions table:

jruby -S rake sds_config:setup_all_config_versions

After starting the SDS you will need to create a Portal Realm to work with. You can do this in the browser interface however you can also do it from the command line using the rails command script/runner.

jruby script/runner 'Portal.create(
:name => "TEST SDS Portal Realm", :use_authentication => false, 
:auth_username => "username", :auth_password => "password", 
:title => "TEST SDS Portal Realm", :vendor => "Concord Consortium", 
:home_page_url => "http://www.concord.org/", :description => "A test.", 
:image_url => "/images/butterfly64x64.png", :last_bundle_only =>  false)'

If you are writing a script to do this the code above can all be on one line.

Running the SDS using the Ruby web application server Mongrel

When running locally, simply run this command from the SDS root directory:

$ jruby script/server -p 3001
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3001
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3001
** Starting Rails with development environment...
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
** Rails signals registered.  HUP => reload (without restart).  It might not work well.
** Mongrel 1.1.4 available at 0.0.0.0:3001
** Use CTRL-C to stop.
Warning

JRuby doesn't allow calls to kernel.fork() by default. The workgroup-pdf-generator application relies on fork().
The workaround is to enable forking when launching the workgroup-pdf-generator:
jruby -J-Djruby.fork.enabled=true ./script/server

All of the steps up to now in one shell script

If you were starting from scratch or just wanted to have another install of the JRuby and the SDS to experiment with here is a shell script that combines all of the previous steps together. This script assumes you are executing it in the directory in which you would like the JRuby and SDS installation created.

For example if this is the working directory when the install_jruby_and_sds.sh script is executed:

~/dev/test_jruby

Then these directories will be created and populated along with the shell script set_jruby_path.sh. This script can be used when you start working with this instance of JRuby and the SDS after restarting a new shell.

~/dev/test_jruby/jruby/
~/dev/test_jruby/sds/
~/dev/test_jruby/set_jruby_path.sh

Do not use this script to install JRuby and the SDS into a system folder.

Prerequisites: Java 1.5 or 1.6 and Ant version 1.6 or higher.

Running this script:

  1. Downloads a subversion checkout of trunk JRuby and builds it (lines 2..4)
  2. Adds the new jruby/bin directory to the end of the environmental variable $PATH (line 5, this will only work correctly if this is the only jruby that can be found on the path).
  3. Installs the necessary Gems into this new version of JRuby (lines 6..11).
  4. Creates a shell script set_jruby_path.sh for use later (lines 13-14).
  5. Downloads a subversion checkout of the trunk SDS (line 15).
  6. Configures the SDS to use the H2 Java database (line 17).
  7. Copies environment.sample.rb to config/environment.rb (line 18).
  8. Creates the database and initializes the config_versions table (lines 19-20).
  9. Creates an initial Portal Realm (lines 21-26, H2 starts it's primary keys at 0 so this will be Portal 0).
  10. Starts the SDS on port 3001 (line 27).
#!/bin/sh
svn co http://svn.codehaus.org/jruby/trunk/jruby jruby
cd jruby
ant; ant jar-complete; ant create-apidocs
export PATH=$PATH:`pwd`/bin
jruby -S gem install rails mongrel
jruby -S gem install jdbc-mysql jdbc-h2
jruby -S gem install activerecord-jdbcmysql-adapter activerecord-jdbch2-adapter
jruby -S gem install warbler --source http://caldersphere.net
curl http://www.telscenter.org/confluence/download/attachments/20236/hpricot-0.6.159-java.gem > hpricot-0.6.159-java.gem
jruby -S gem install hpricot-0.6.159-java.gem
cd ..
echo 'PATH=$PATH:`pwd`/jruby/bin' > set_jruby_path.sh
chmod +x set_jruby_path.sh
svn co https://svn.concord.org/svn/sds/trunk sds
cd sds
cp config/database_sample_h2.yml config/database.yml
cp config/environment.sample.rb config/environment.rb
jruby -S rake db:migrate
jruby -S rake sds_config:setup_all_config_versions
jruby script/runner 'Portal.create(
:name => "TEST SDS Portal Realm", :use_authentication => false, 
:auth_username => "username", :auth_password => "password", 
:title => "TEST SDS Portal Realm", :vendor => "Concord Consortium", 
:home_page_url => "http://www.concord.org/", :description => "A test.", 
:image_url => "/images/butterfly64x64.png", :last_bundle_only =>  false)'
jruby script/server -p 3001

Note: this script does not yet also install or integrate the workgroup-pdf-generator.

Deploying a Rails Application to a Java Application Server

At this point I recommend using Warbler to package the SDS Rails application into a WAR file for deployment. Nick Sieger describes Warbler like this:

Warbler is a gem to make a .war file out of a Rails project. The intent is to provide a minimal, flexible, ruby-like way to bundle up all of your application files for deployment to a Java application server. Warbler provides a sane set of out-of-the box defaults that should allow most Rails applications without external gem dependencies (aside from Rails itself) to assemble and Just Work. Warbler bundles JRuby and the Goldspike servlet for dispatching requests to your application inside the java application server, and assembles all jar files in WARBLER_HOME/lib/*.jar into your application. No external dependencies are downloaded.

In addition you will be using

  • the trunk version of jruby-complete.jar you created when ran the ant task ant jar-complete earlier.
  • a snapshot version (jruby-rack-1.0-SNAPSHOT.jar) of the JRuby Rack servlet adaptor.

About JRuby Rack

JRuby Rack is a JRuby implementation of the Rack Ruby web adapter layer and should be used instead of GoldSpike.

From the REAME.txt:

JRuby-Rack is a lightweight adapter for the Java servlet environment that allows any Rack-based application to run unmodified in a Java servlet container. JRuby-Rack supports Rails, Merb, as well as any Rack-compatible Ruby web framework.

I've built a SNAPSHOT version and attached to this Confluence page so building it yourself is not necessary. Here are the building instructions for reference:

Building a trunk version of JRuby Rack

You need a trunk version of JRuby to complete this build so make sure you are in a shell with your $PATH environmental variable setup to include $JRUBY_HOME/bin.

  1. Install the prerequisite Gems buildr (A Ruby replacement for Maven) and rack (lines 1-2).
  2. Checkout the JRuby Rack code and cd to that directory (lines 3-4).
  3. Resolve dependencies, compile the code, and build the jar file (line 6).
    jruby -S gem install buildr --source http://caldersphere.net
    jruby -S gem install rack
    svn co http://svn.codehaus.org/jruby-contrib/trunk/rack
    cd rack
    jruby -S buildr package
  4. The generated jar should be located here: target/jruby-rack-1.0-SNAPSHOT.jar.

FYI: Buildr is an active Apache project with incubation status. It is intended to be a drop-in replacement for Maven 2.0, Buildr uses the same file layout, artifact specifications, local and remote repositories

Converting the Simple Rails Blog application to a WAR file

The simple blog application is a good test case to try and get working in a WAR deployment. In all the steps below I assume the working directory is the blog application,

  1. Generate a custom Warbler WAR configuration for the blog application
    jruby -S warble config
  2. Generate a production version of the H2 database for the blog application:
    RAILS_ENV=production jruby -S rake db:migrate
  3. Edit this file: config/environment.rb and add the last four lines listed below:
    # Bootstrap the Rails environment, frameworks, and default configuration
    require File.join(File.dirname(__FILE__), 'boot')
    
    if RUBY_PLATFORM =~ /java/
      require 'rubygems'
      RAILS_CONNECTION_ADAPTERS = %w(jdbc)
    end

    This will make sure that Rails will be able to find the ActiveRecord JDBC connection adaptors.

  4. Edit this file: config/warble.rb and add the following line after these comments:
    # Additional files/directories to include, above those in config.dirs
    # config.includes = FileList["db"] 
    config.includes = FileList["db/production_h2*"]

    This will tell Warble to include the just initialized production H2 database in the WAR.

  5. Continue editing config/warble.rb and add the following line after these comments:
    # Additional Java .jar files to include.  Note that if .jar files are placed
    # in lib (and not otherwise excluded) then they need not be mentioned here
    # JRuby and Goldspike are pre-loaded in this list.  Be sure to include your
    # own versions if you directly set the value
    # config.java_libs += FileList["lib/java/*.jar"]
    config.java_libs = []

    This will tell Warble to not include the jars jruby-complete-1.1RC2, goldspike-1.5, commons-pool-1.3.jar, and activation-1.1.jar. You will be replacing these with the trunk version of jruby-complete.jar and jruby-rack-1.0-SNAPSHOT.jar (a replacement for goldspike).

  6. Continue editing config/warble.rb and add the following line after these comments:
    # Gems to be packaged in the webapp.  Note that Rails gems are added to this
    # list if vendor/rails is not present, so be sure to include rails if you
    # overwrite the value
    # config.gems = ["activerecord-jdbc-adapter", "jruby-openssl"]
    # config.gems << "tzinfo"
    # config.gems["rails"] = "1.2.3" 
    %w{jdbc-h2 activerecord-jdbch2-adapter activerecord-jdbc-adapter}.each {|g| config.gems << g}

    This will tell Warble to add the JDBC driver for H2 as well as the ActiveRecord JDBC and JDBC-H2 adaptor Gems.

  7. Copy the trunk version of jruby-complete.jar you created when ran the ant task ant jar-complete earlier into the blog/lib directory:
    cp ../jruby/lib/jruby-complete.jar lib/
  8. Download the snapshot version of the jruby-rack-1.0-SNAPSHOT jar into the blog/lib directory:
    curl http://www.telscenter.org/confluence/download/attachments/20236/jruby-rack-1.0-SNAPSHOT.jar > lib/jruby-rack-1.0-SNAPSHOT.jar
  9. Now generate the WAR file:
    jruby -S warble war

    This task generates the file: blog.war at the top level of the application as well as an exploded version of the war located here: tmp/war.

When you make changes in your application or config/warble.rb that causes a resource to be deleted that was previously included in the WAR run this task to actually remove it from the WAR:

jruby -S warble war:clean

You can check on what Warbler packaged up as Gems. The list should look like this:

$ jruby -S warble war:debug:gems

gems files:
tmp/war/WEB-INF/gems/specifications/rails-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/rake-0.8.1.gemspec
tmp/war/WEB-INF/gems/specifications/activesupport-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/activerecord-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/actionpack-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/actionmailer-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/activeresource-2.0.2.gemspec
tmp/war/WEB-INF/gems/specifications/jdbc-h2-1.0.63.gemspec
tmp/war/WEB-INF/gems/specifications/activerecord-jdbch2-adapter-0.7.2.gemspec
tmp/war/WEB-INF/gems/specifications/activerecord-jdbc-adapter-0.7.2.gemspec

Confirm that the Warbler default jars ({jruby-complete-1.1RC2}}, goldspike-1.5, commons-pool-1.3.jar, and activation-1.1.jar) are no longer being included:

$ jruby -S warble war:debug:java_libs

java_libs files:

You can get a listing of everything app-specific Warbler is planning to include with this task:

$ jruby -S warble war:debug:app

app files:
...

Make sure you see these files in your list (though I don't think this file: production_h2_database.56824.temp.db is needed):

tmp/war/WEB-INF/db/production_h2_database.56824.temp.db
tmp/war/WEB-INF/db/production_h2_database.6.log.db
tmp/war/WEB-INF/db/production_h2_database.data.db
tmp/war/WEB-INF/db/production_h2_database.index.db
tmp/war/WEB-INF/db/production_h2_database.lock.db
tmp/war/WEB-INF/db/production_h2_database.trace.db

tmp/war/WEB-INF/lib/jruby-complete.jar
tmp/war/WEB-INF/lib/jruby-rack-1.0-SNAPSHOT.jar

You can display a more detailed view of the decisions and configuration interpretations Warbler is using to construct the WAR with this command:

jruby -S warble war:debug

And of course you can also inspect the exploded WAR at tmp/war or execute jar tf blog.war to display a list of all the files in the actual WAR file.

Converting the SDS application to a WAR file

incomplete

Some external links (may be somewhat out of date):

Deploying the WAR file to Tomcat

  1. download tomcat 5.5.x: http://tomcat.apache.org/download-55.cgi
    curl http://mirror.cc.columbia.edu/pub/software/apache/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.tar.gz > tomcat-5.5.26.tar.gz
    

    this will create a file called tomcat-5.5.26.tar.gz

  2. unzip and untar tomcat
    gunzip tomcat-5.5.26.tar.gz
    tar -xf tomcat-5.5.26.tar
    
  3. Define a CATALINA_HOME system variable. This represents the root of your Tomcat installation
    export CATALINA_HOME=`pwd`/apache-tomcat-5.5.26
    
  4. Add CATALINA_HOME/bin to the system path. On unix systems, you can do this by adding "export CATALINA_HOME=/path/to/tomcat" in your $HOME/.profile file, or run this comment:
    export PATH=$CATALINA_HOME/bin:$PATH
    
  5. copy war file into CATALINA_HOME/webapps directory.
    cp WARFILE $CATALINA_HOME/webapps
    
  6. start up tomcat
    $ cd $CATALINA_HOME/bin
    $ ./startup.sh
    
  7. go to http://localhost:8080/NAME_OF_WARFILE. You should see your application.

Steps 5-7 can be done using the Tomcat Web Application Manager.

  1. Configure personal settings for Tomcat.
    In CATALINA_BASE/conf/tomcat-users.xml file, you need to add a new "manager" role as well as a new user that has been granted the manager role.
    <tomcat-users>
     	...
     	<role rolename="manager"/>
     	<user username="myuser" password="mypass" roles="manager"/>
     	...
     	</tomcat-users>
    
  2. go to http://localhost:8080. You should see a Tomcat webpage.
  3. Click on "Tomcat Manager" in the Administration section on the left. This will ask you for a log in. Use the myuser/mypass login that you defined above. Once authorized, you will see the Tomcat Web Application Manager that lists all the deployed web applications along with some commands.
  4. Deploy the War file. Use the "WAR file to deploy" section to choose the war file and deploy. If successful, your web application will be listed along with other deployed web applications.
  5. Click on the web application. It will take you to http://localhost:8080/NAME_OF_WARFILE

Testing the REST API access to the Simple Rails Blog application deployed as a WAR

The REST API access should work just the same as before except the host port number is now 8080 and the path to the application now starts with /blog. Here's an example that shows an additional comment being created using the command line program curl.

curl -i -H 'Content-Type: application/xml' -X POST -d '<comment><name>third comment</name>
<body>This comment was created using a REST request with curl.</body></comment>' http://localhost:8080/blog/comments
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.