Friday Sep 18, 2009

Free Rails/GlassFish Webinar with live Q&A: Sep 23, 2009,10am PT

Got the following message in my inbox today:

All details (including registration) are available here.

Looking forward to see you there!

Technorati: glassfish rubyonrails jruby webinar

Thursday Sep 17, 2009

TOTD #104: Popular Ruby-on-Rails applications on GlassFish v3 – Redmine, Typo, Substruct

GlassFish v3 is opening up new frontiers by allowing to easily deploy Rails, Grails and Django applications, in addition to Java EE, without any additional packaging. You can even write a custom container to support new types of applications. Numerous entries on this blog have talked about how to deploy Rails applications on GlassFish v3. This Tip Of The Day (TOTD) will recap them and, once again, demonstrate how to easily get started with deploying some popular open source Rails applications on GlassFish v3.

Lets prepare a GlassFish v3 build for deploying Rails applications. This blog is going to use 9/16 nightly but you should pick the latest nightly or promoted.

  1. Unzip the downloaded bundle as:
    ~/tools/glassfish/v3/9-16 >unzip ~/Downloads/
  2. Configure JRuby/Rails in GlassFish v3 - JRuby/rails can be configured three different ways - use a previously installed JRuby/Rails directory, install JRuby/Rails module using the graphical Update Center or the "pkg" binary. This Update Center module comes packaged with JRuby 1.3.1, Rails 2.3.2 and some other useful gems. Pick the option you are most comfortable with and use it for your GlassFish installation.
    1. Configure previously installed JRuby/Rails directory as:
      ~/tools/glassfish/v3/9-16/glassfishv3/bin/asadmin create-jvm-options -Djruby.home=/Users/arungupta/tools/jruby
      Authentication failed with password from login store: /Users/arungupta/.asadminpass
      Enter admin password >
      created 1 option(s)
      Command create-jvm-options executed successfully.

      That's it!
    2. Install JRuby/Rails module using graphical Update Tool
      1. The graphical Update Tool tool can be invoked as:
        ~/tools/glassfish/v3/9-16/glassfishv3 >./bin/updatetool
        The software needed for this command (updatetool) is not installed.
        If you choose to install Update Tool, your system will be automatically
        configured to periodically check for software updates. If you would like
        to configure the tool to not check for updates, you can override the
        default behavior via the tool's Preferences facility.
        When this tool interacts with package repositories, some system information
        such as your system's IP address and operating system type and version
        is sent to the repository server. For more information please see:
        Once installation is complete you may re-run this command.
        Would you like to install Update Tool now (y/n): y
        Proxy: Using system proxy settings.
        Install image: /Users/arungupta/tools/glassfish/v3/9-16/glassfishv3
        Installing pkg packages.
        Installing updatetool packages.
        Registering notifier: Already registered.
        Initialization complete.
        Software successfully installed. You may now re-run this command (updatetool).
      2. The first invocation of the command installs the Update Tool and the second invocation shows the following screen after "JRuby on GlassFish" module is selected:

        Click on green button in the top left to install the module and it picks up the dependencies as well as shown below:

        Click on "Install" to start the installation and click on "Accept" to accept the license.
      3. Close the Update Tool window once the installation is completed. The module creates "glassfish/jruby" directory.
    3. Install JRuby/Rails module using "pkg" binary
      1. Install the JRuby/Rails bits using the "pkg" binary. Invoke the command as:
        ~/tools/glassfish/v3/9-16/glassfishv3 >./bin/pkg

        The software needed for this command (pkg) is not installed. When this tool interacts with package repositories, some system information such as your system's IP address and operating system type and version is sent to the repository server. For more information please see: Once installation is complete you may re-run this command. Would you like to install this software now (y/n): y Proxy: Using system proxy settings. Install image: /Users/arungupta/tools/glassfish/v3/9-16/glassfishv3 Installing pkg packages. Initialization complete. Software successfully installed. You may now re-run this command (pkg).
      2. The command "pkg list -a" shows all the modules available for installation and the output looks like:

        ~/tools/glassfish/v3/9-16/glassfishv3 >./bin/pkg list -a
        NAME (PUBLISHER)                              VERSION         STATE      UFIX
        ant (                   1.7.1-0.6       known      ----
        felix                                         2.0.0-0         installed  ----
        glassfish-appclient                           3.0-65          installed  ----
        glassfish-cmp                                 3.0-65          installed  ----
        . . .
        jersey-docs-and-examples                      1.1.2-1.0       known      ----
        jmaki (                 1.8.1-2.0       known      ----
        jruby                                         1.3.1-1.1       known      ----
        jruby (                 1.2.0-1.1       known      u---
        jruby-gems (            2.3.2-1.1       known      ----
        jython-container (      0.5.3-1.0       known      ----
        jython-runtime (        2.5.0-1.0       known      ----
        metro                                         2.0-19          installed  ----
        . . .
        updatetool                                    2.3.0-36.2403   known      ----
        updatetool (            2.2.2-30.2311   known      u---
        wxpython2.8-minimal                  known      ----
        wxpython2.8-minimal (   2.8.8-30.2311   known      u---
      3. Start the installation of "jruby" module as:

        ~/tools/glassfish/v3/9-17/glassfishv3 >./bin/pkg install jruby
        DOWNLOAD                                  PKGS       FILES    XFER (MB)
        Completed                                  2/2 14810/14810    37.0/37.0
        PHASE                                        ACTIONS
        Install Phase                            17273/17273
  3. Redmine on GlassFish - Redmine is an open source project management web application. The simplified steps to deploy Redmine on GlassFish v3 are given below (also on GlassFish Gem and on GlassFish v3 TP2):
    1. Download and unzip Redmine 0.8.5 (latest stable release).
    2. Change the database adapter from "mysql" to "jdbcmysql" as:

      sed s/'adapter: mysql'/'adapter: jdbcmysql'/ <config/ >config/database.yml
    3. Create the database manually as "sudo mysqladmin create redmine_development". "db:create" fails because of JRUBY-3502.
    4. Migrate the database as "db:migrate".
    5. Deploy the application as:
      ~/samples/jruby/redmine >~/tools/glassfish/v3/9-16/glassfishv3/bin/asadmin deploy redmine-0.8.5
       Authentication failed with password from login store: /Users/arungupta/.asadminpass
      Enter admin password>
      Command deploy executed successfully.
    6. Here are some snapshots from the deployed application:

  4. Typo on GlassFish - Typo is the oldest Ruby on Rails blogware. The simplified steps to deploy Typo on GlassFish v3 are given below (also on GlassFish Prelude):
    1. Download and unzip Typo 5.3 (latest stable release).
    2. Change the database adapter from "mysql" to "jdbcmysql" as:

      sed s/'adapter: mysql'/'adapter: jdbcmysql'/ <config/database.yml.example >config/database.yml
    3. Create the database manually as "sudo mysqladmin create typo_dev". "db:create" fails because of JRUBY-3502.
    4. Typo runs using Rails 2.2.2 so lets install Rails 2.2.2 so lets install Rails 2.2.2 as:
      ~/samples/jruby/typo/typo-5.3 >~/tools/glassfish/v3/9-16/glassfishv3/glassfish/jruby/bin/jruby -S gem install rails -v 2.2.2
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      Successfully installed activesupport-2.2.2
      Successfully installed activerecord-2.2.2
      Successfully installed actionpack-2.2.2
      Successfully installed actionmailer-2.2.2
      Successfully installed activeresource-2.2.2
      Successfully installed rails-2.2.2
      6 gems installed
      Installing ri documentation for activesupport-2.2.2...
      Installing ri documentation for activerecord-2.2.2...
      Installing ri documentation for actionpack-2.2.2...
      Installing ri documentation for actionmailer-2.2.2...
      Installing ri documentation for activeresource-2.2.2...
      Installing ri documentation for rails-2.2.2...
      Installing RDoc documentation for activesupport-2.2.2...
      Installing RDoc documentation for activerecord-2.2.2...
      Installing RDoc documentation for actionpack-2.2.2...
      Installing RDoc documentation for actionmailer-2.2.2...
      Installing RDoc documentation for activeresource-2.2.2...
      Installing RDoc documentation for rails-2.2.2...
    5. Migrate the database as "db:migrate".
    6. Deploy the application as:
      ~/samples/jruby/typo >~/tools/glassfish/v3/9-16/glassfishv3/bin/asadmin deploy typo-5.3
      Authentication failed with password from login store: /Users/arungupta/.asadminpass
      Enter admin password>
      Command deploy executed successfully.
    7. Here are are some snapshots from the deployed application:

  5. Substruct on GlassFish - Substruct is an open source E-Commerce project in Ruby-on-Rails. The simplified steps to deploy Substruct on GlassFish v3 are given below (also on GlassFish v3 Gem):
    1. Download and unzip substruct 1.0 a6 (latest stable release).
    2. Install the required gems as:
      ~/samples/jruby/substruct >~/tools/glassfish/v3/9-16/glassfishv3/glassfish/jruby/bin/jruby -S gem install RedCloth fastercsv mime-types mini_magick ezcrypto jruby-openssl --no-ri --no-rdoc
    3. Change the database adapter from "mysql" to "jdbcmysql" as:

      ~/samples/jruby/substruct/substruct_rel_1-0-a6>sed s/'adapter: mysql'/'adapter: jdbcmysql'/ <config/database.yml
      ~/samples/jruby/substruct/substruct_rel_1-0-a6>mv config/ config/database.yml
    4. Create the database manually as "sudo mysqladmin create substruct_development". "db:create" fails because of JRUBY-3502.
    5. Initialize the database as:
      ~/samples/jruby/substruct/substruct_rel_1-0-a6 >~/tools/glassfish/v3/9-16/glassfishv3/glassfish/jruby/bin/jruby -S rake substruct:db:bootstrap
    6. Deploy the application as:
      ~/samples/jruby/substruct >~/tools/glassfish/v3/9-16/glassfishv3/bin/asadmin deploy substruct_rel_1-0-a6
      Authentication failed with password from login store: /Users/arungupta/.asadminpass
      Enter admin password>
      Command deploy executed successfully.
    7. Here is a snapshot of the deployed application:

So we deployed Redmine, Typo, and Substruct using JRuby/Rails on GlassFish without any additional packaging. There are several Rails applications deployed in production on GlassFish.

What Rails applications are you deploying on GlassFish ?

Technorati: glassfish v3 rubyonrails jruby redmine typo mephisto substruct

Tuesday Aug 11, 2009

TOTD #92: Session Failover for Rails applications running on GlassFish

The GlassFish High Availability allows to setup a cluster of GlassFish instances and achieve highly scalable architecture using in-memory session state replication. This cluster can be very easily created and tested using the "clusterjsp" sample bundled with GlassFish. Here are some clustering related entries published on this blog so far:
  • TOTD #84 shows how to setup Apache + mod_proxy balancer for Ruby-on-Rails load balancing
  • TOTD #81 shows how to use nginx to front end a cluster of GlassFish Gems
  • TOTD #69 explains how a GlassFish cluster can be front-ended using Sun Web Server and Load Balancer Plugin
  • TOTD #67 shows the same thing using Apache httpd + mod_jk
#67 & #69 uses a web application "clusterjsp" (bundled with GlassFish) that uses JSP to demonstrate in-memory session replication state replication. This blog creates a similar application "clusterrails" - this time using Ruby-on-Rails and deploy it on GlassFish v2.1.1. The idea is to demonstrate how Rails applications can leverage the in-memory session replication feature of GlassFish.

Rails applications can be easily deployed as a WAR file on GlassFish v2 as explained in TOTD #73. This blog will guide through the steps of creating the Controller and View to mimic "clusterjsp" and configuring the Rails application for session replication.
  1. Create a template Rails application and create/migrate the database. Add a Controller/View as:

    ~/samples/jruby/session >~/tools/jruby/bin/jruby script/generate controller home index
    JRuby limited openssl loaded. gem install jruby-openssl for full support.
          exists  app/controllers/
          exists  app/helpers/
          create  app/views/home
          exists  test/functional/
          create  test/unit/helpers/
          create  app/controllers/home_controller.rb
          create  test/functional/home_controller_test.rb
          create  app/helpers/home_helper.rb
          create  test/unit/helpers/home_helper_test.rb
          create  app/views/home/index.html.erb

  2. Edit the controller in "app/controllers/home_controller.rb" and change the code to (explained below):

    class HomeController < ApplicationController
      include Java

      def index
        @server_served = servlet_request.get_server_name
        @port = servlet_request.get_server_port
        @instance = java.lang.System.get_property "com.sun.aas.instanceName"
        @server_executed =
        @ip =
        @session_id = servlet_request.session.get_id
        @session_created = servlet_request.session.get_creation_time
        @session_last_accessed = servlet_request.session.get_last_accessed_time
        @session_inactive = servlet_request.session.get_max_inactive_interval

        if (params[:name] != nil)
          servlet_request.session[params[:name]] = params[:value]

        @session_values = ""
        value_names = servlet_request.session.get_attribute_names
        unless (value_names.has_more_elements)
          @session_values = "<br>No parameter entered for this request"
            @session_values << "<UL>"
            while (value_names.has_more_elements)
                param = value_names.next_element
                unless (param.starts_with?("__"))
                  value = servlet_request.session.get_attribute(param)
                  @session_values << "<LI>" + param + " = " + value + "</LI>"
            @session_values << "</UL>"


      def adddata
        servlet_request.session.set_attribute(params[:name], params[:value])
        render :action => "index"

      def cleardata
        render :action => "index"

    The "index" action initializes some instance variables using the "servlet_request" variable mapped from "javax.servlet.http.ServletRequest" class. The "servlet_request" provides access to different properties of the request received such as server name/port, host name/address and others. It also uses an application server specific property "com.sun.aas.instanceName" to fetch the name of particular instance serving the request. In this blog we'll create a cluster with 2 instances. The action then prints the servlet session attributes name/value pairs entered so far.

    The "adddata" action takes the name/value pair entered on the page and stores them in the servlet request. The "cleardata" action clears any data that is storied in the session.
  3. Edit the view in "app/views/home/index.html.erb" and change to (explained below):

    <p>Find me in app/views/home/index.html.erb</p>
    <B>HttpSession Information:</B>
    <LI>Served From Server:   <b><%= @server_served %></b></LI>
    <LI>Server Port Number:   <b><%= @port %></b></LI>
    <LI>Executed From Server: <b><%= @server_executed %></b></LI>
    <LI>Served From Server instance: <b><%= @instance %></b></LI>
    <LI>Executed Server IP Address: <b><%= @ip %></b></LI>
    <LI>Session ID:    <b><%= @session_id %></b></LI>
    <LI>Session Created:  <%= @session_created %></LI>
    <LI>Last Accessed:    <%= @session_last_accessed %></LI>
    <LI>Session will go inactive in  <b><%= @session_inactive %> seconds</b></LI>
    <% form_tag "/session/home/index" do %>
      <label for="name">Name of Session Attribute:</label>
      <%= text_field_tag :name, params[:name] %><br>

      <label for="value">Value of Session Attribute:</label>
      <%= text_field_tag :value, params[:value] %><br>

        <%= submit_tag "Add Session Data" %>
    <% end  %>
    <% form_tag "/session/home/cleardata" do %>
        <%= submit_tag "Clear Session Data" %>
    <% end %>
    <% form_tag "/session/home/index" do %>
        <%= submit_tag "Reload Page" %>
    <% end %>
    <B>Data retrieved from the HttpSession: </B>
    <%= @session_values %>

    The view dumps the property value retrieved from the servlet context in the action. Then it consists of some forms to enter the session name/value pairs, clear the session and reload the page. The application is now ready, lets configure it for WAR packaging.
  4. Generate a template "web.xml" and copy it to "config" directory as:

    ~/samples/jruby/session >~/tools/jruby/bin/jruby -S warble war:webxml
    mkdir -p tmp/war/WEB-INF
    ~/samples/jruby/session >cp tmp/war/WEB-INF/web.xml config/
    1. Edit "tmp/war/WEB-INF/web.xml" and change the first few lines from:

      <!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"


      <web-app version="2.4" xmlns="" xmlns:xsi="" xsi:schemaLocation="">

      This is required because the element to be added next is introduced in the Servlet 2.4 specification.
    2. Add the following element:


      as the first element, right after "<web-app>". This element marks the web application to be distributable across multiple JVMs in a cluster.
  5. Generate and configure "warble/config.rb" as described in TOTD #87. This configuration is an important step otherwise you'll encounter JRUBY-3789. Create a WAR file as:

    ~/samples/jruby/session >~/tools/jruby/bin/jruby -S warble
    mkdir -p tmp/war/WEB-INF/gems/specifications
    cp /Users/arungupta/tools/jruby-1.3.0/lib/ruby/gems/1.8/specifications/rails-2.3.2.gemspec tmp/war/WEB-INF/gems/specifications/rails-2.3.2.gemspec

    . . .

    mkdir -p tmp/war/WEB-INF
    cp config/web.xml tmp/war/WEB-INF
    jar cf session.war  -C tmp/war .

  6. Download latest GlassFish v2.1.1, install/configure GlassFish and create/configure/start a cluster using the script described here. Make sure to change the download location and filename in the script. This script creates a cluster "wines" with two instances - "cabernet" runing on the port 58080 and "merlot" running on the port 58081.
  7. Deploy the application using the command:

    ~/samples/jruby/session >asadmin deploy --target wines --port 5048 --availabilityenabled=true session.war
Now, the screenshots from the two instances are shown and explained below. The two (or more) instances are front-ended by a load balancer so none of this is typically visible to the user but it helps to understand.
Here is a snapshot of this application deployed on "cabernet":

The instance name and the session id is highlighted in the red box. It also shows the time when the session was created in "Session Created" field.

And now the same application form "merlot":

Notice, the session id exactly matches the one from the "cabernet" instance. Similarly "Session Created" matches but "Last Accessed" does not because the same session session is accessed from a different instance.

Lets enter some session data in the "cabernet" instance and click on "Add Session Data" button as shown below:

The session attribute is "aaa" and value is "111". Also the "Last Accessed" time is updated. In the "merlot" page, click on the "Reload Page" button and the same session name/value pairs are retrieved as shown below:

Notice, the "Last Accessed" time is after the time showed in "cabernet" instance. The session information added in "cabernet" is automatically replicated to the "merlot" instance.

Now, lets add a new session name/value pair in "merlot" instance as shown below:

The "Last Accessed" is updated and the session name/value pair ("bbb"/"222") is shown in the page. Click on "Reload page" in "cabernet" instance as shown below:

This time the session information added to "merlot" is replicated to "cabernet".

So any session information added in "cabernet" is replicated to "merlot" and vice versa.

Now, lets stop "cabernet" instance as shown below:

and click on "Reload Page" in "merlot" instance to see the following:

Even though one instance from which the session data was added is stopped, the replicating instance continues to serve both the session values.

As explained earlier, these two instances are front-ended by a load-balancer typically running at port 80. So the user makes a request to port 80 and the correct session values are served even if one of the instance goes down and there by providing in-memory session replication.

Please leave suggestions on other TOTD that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish clustering rubyonrails jruby highavailability loadbalancer

Sunday Aug 02, 2009

TOTD #88: How add pagination to Rails - will_paginate

This Tip Of The Day (TOTD) explains how to add pagination to your Rails application.
  1. Create a simple Rails scaffold as:

    ~/samples/jruby >~/tools/jruby/bin/jruby -S rails paginate
    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby script/generate scaffold book title:string author:string
    ~/samples/jruby/paginate >sed s/'adapter: sqlite3'/'adapter: jdbcsqlite3'/ <config/database.yml >config/
    ~/samples/jruby/paginate >mv config/ config/database.yml
    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S rake db:migrate

  2. Edit "test/fixtures/books.yml" and specify the content as:

    # Read about fixtures at

      title: Ultramarathon Man Confessions of an All-Night Runner
      author: Dean Karnazes

      title: My Life on the Run
      author: Bart Yasso

      title: 50/50 Secrets I Learned Running 50 Marathons in 50 Days
      author: Dean Karnazes

      title: Born to Run
      author: Christopher Mcdougall

      title: Four Months to a Four-hour Marathon
      author: Dave Kuehls

      title:  Galloway's Book on Running
      author: Jeff Galloway

      title: Marathoning for Mortals
      author: John Bingham and Jenny Hadfield

      title:  Marathon You Can Do It!
      author: Jeff Galloway

      title: Marathon The Ultimate Training Guide
      author: Hal Higdon

      title: Running for Mortals
      author: John Bingham and Jenny Hadfield

    and load the fixtures as:

    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S rake db:fixtures:load
    (in /Users/arungupta/samples/jruby/paginate)

  3. Run the application as:

    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S glassfish -l
    Starting GlassFish server at: in development environment...
    Writing log messages to: /Users/arungupta/samples/jruby/paginate/log/development.log.

    . . .

    Jul 29, 2009 2:06:44 PM com.sun.grizzly.scripting.pool.DynamicPool$1 run
    INFO: New instance created in 7,488 milliseconds

    The application is accessible at "http://localhost:3000/books" and looks like:

    The page shows 10 rows, all in one page.
  4. Lets add pagination to this simple sample.
    1. Install will_paginate gem as:

      /tools/jruby >./bin/jruby -S gem install will_paginate
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      Successfully installed will_paginate-2.2.2
      1 gem installed
      Installing ri documentation for will_paginate-2.2.2...
      Installing RDoc documentation for will_paginate-2.2.2...

      There are other methods of installation as well.
    2. Edit "config/environment.rb" and add

      require "will_paginate"

      as the last line.
    3. Edit the "index" action in "app/controllers/books_controller.rb" as:

      @books = Book.paginate(:page => params[:page], :per_page => 5)
      #@books = Book.all

      ":per_page" specifies the number of items to be displayed in each page.
    4. In "app/views/books/index.html.erb", add:

      <%= will_paginate @books %>

      right after "</table>".

      The output now looks like:

      and clicking on "Next" shows:

      The information is nicely split amongst 2 pages.
An important point to remember is that will_paginate only adds pagination to your Rails app. You are still required to display all the values.

But essentially replacing "@books = Book.all" with "@books = Book.paginate(:page => params[:page], :per_page => 5)" in the Controller and adding
"<%= will_paginate @books %>" did the trick for us.

Clean and simple!

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all the tips is available here.

Technorati: jruby rubyonrails glassfish pagination will_paginate

Thursday Jul 30, 2009

TOTD #87: How to fix the error undefined method `new' for "Rack::Lock":String caused by Warbler/JRuby-Rack ?

If you are using Warbler to create a WAR file of your application and deploying on GlassFish or any other Servlet container, then you are likely seeing the following error during deployment:

[/session]unable to create shared application instance
org.jruby.rack.RackInitializationException: undefined method `new' for "Rack::Lock":String
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/middleware_stack.rb:116:in `inject'
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/middleware_stack.rb:116:in `build'
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/dispatcher.rb:82:in `initialize'

. . .

This is a known issue as reported at JRUBY-3789 and JRUBY_RACK-18.

As the bug report indicates, this is actually an issue with jruby-rack-0.9.4 and is fixed in jruby-rack-0.9.5. The 3-step workaround is described here and explained below for convenience:
  1. Do "warble war:clean" to clean up the .war file and staging area. This basically removes previous version of jruby-rack.jar.
  2. Download the latest jruby-rack-0.9.5 snapshot (complete list) and copy in the "lib" directory of your application.
  3. If "config/warble.rb" does not exist then generate it using "jruby -S config warble". Edit "config/warble.rb" such that it looks like:

      # 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 JRuby-Rack 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.delete_if {|f| f =~ /jruby-rack/ }
      config.java_libs += FileList["lib/jruby-rack\*.jar"]

    This will pack jruby-rack-0.9.5 snapshot instead of the one bundled with Warbler.

    Now warbler 1.0.0 bundles "jruby-complete-1.3.0RC1.jar". Optionally, you can also download the latest jruby-complete (jruby-complete-1.3.1.jar as of this writing) and copy in the "lib" directory of your application. In that case, modify the above fragment to:

      # 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 JRuby-Rack 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.delete_if {|f| f =~ /jruby-rack/ || f =~ /jruby-complete/ }
      config.java_libs += FileList["lib/jruby-complete\*.jar"]
      config.java_libs += FileList["lib/jruby-rack\*.jar"]

    This packs the "jruby-complete-1.3.1.jar" in your .war file.
And now follow your regular procedure of creating the .war file using "jruby -S warble" and happily deploy your Rails/Sintara/Merb applications on GlassFish.

There are several users who are already using Rails on GlassFish in production environment and they are listed at rubyonrails+glassfish+stories. Drop a comment on this blog if you are using it too :)

Technorati: jruby rack glassfish war servlet rubyonrails

Tuesday Jul 28, 2009

Track your running miles using JRuby, Ruby-on-Rails, GlassFish, NetBeans, MySQL, and YUI Charts

This blog introduces a new application that will provide basic tracking of your running distance and generate charts to monitor progress. There are numerous similar applications that are already available/hosted and this is a very basic application. What's different about this ?

The first version of this application is built using JRuby, Ruby-on-Rails, GlassFish Gem, MySQL, and NetBeans IDE. This combination of technologies is a high quality Rails stack that is used in production deploymnet at various places. Still nothing different ?

A similar version of this application will be built using a variety of Web frameworks such as Java EEGrails, Wicket, Spring and Struts2 (in no particular order). The goal is to provide a similar application, slightly bigger than "Hello World," built using different frameworks and deploy on GlassFish. Each framework will then be evaluated based upon the criteria ranging from the basic principles of framework, ease-of-use in design/development/testing/debugging/production of this web app, database interaction, tools support, ability to add 3rd party libraries, browser compatibility and other points. 

An important point to note is that this is not an exhaustive evaluation of different Web frameworks and the scope is limited only to this application.

A complete list of frameworks planned is available here. The criteria used to evaluate each framework is described here. Your feedback in terms of Web frameworks and evaluation criteria is highly appreciated.  Please share your feedback on the users list.

Now the first version of application. The complete instructions to check out and run the Rails version of this application are available here.

Here are some charts generated using the application:


YUI is used for all the charting capabilities.

And here is a short video that explains how the application work:

If you are a runner, check out the application and use it for tracking your miles. A sample runlog is available in "test/fixtures/runlogs.yml" and races in "test/fixtures/races.yml".

If you know Rails, please provide feedback if the application is DRY and using the right set of helpers.

If you'd like the existing list of web frameworks to be pruned or include another one to the list, let us know.

Share you feedback at

Technorati: jruby rubyonrails glassfish netbeans mysql yahoo yui chart running miles framework

Thursday Jul 02, 2009

Rails on GlassFish - "most performant of all", "simpler and just works", "blazing speed"

Here are some quotes about running Rails applications on GlassFish from user@jruby mailing list:

I find the glassfish gem to be the most performant of all -- and I don't need to war-up my app.

I also have some mongrel cluster stuff, but glassfish is simpler and just works.

Voila...blazing speed, can handle lots of traffic. Note that I am also cominging into apache from a dyndns name. So, whatever IP I have, I can go straight to execution on the glassfish gem and NO warring up! What could be easier deployment, or a faster execution?

It's running fantasticly and performing like nothing I've seen before :) Completely stable memory, no wirings or anything bad for 5 days now.. (with several ab/htperf stresstests).

It's always exciting to get good endorsements of our efforts in the GlassFish team :)

Other similar stories for using Rails/GlassFish in production are described at rubyonrails+stories.

Technorati: glassfish v3 gem rubyonrails stories jruby

Thursday May 14, 2009

Ruby-on-Rails and Ramaze production deployments on GlassFish

Published three new JRuby/GlassFish production deployment stories in as many days:

Who ? Recipe Why GlassFish ?
JRuby + Rails + GlassFish v2 + MySQL + Apache Web Server + memcached The GlassFish processes have been among the most stable of our deployment.


(The) GlassFish team has been extremely helpful along the way with tuning and diagnosing performance issues.
JRuby + Rails + GlassFish v2 + MySQL + Solaris Zones GlassFish works and provides useful error messages.
Recipe: JRuby + Ramaze + GlassFish v2 + MySQL/H2 What's essential for me is that I spend my time doing development, not sysadmin work, so I settle for a working solution.   I've had no trouble for a few months now, and redeploy using simple scripts.

Other similar JRuby stories are available at jruby+stories. Other GlassFish stories are available here.

Technorati: jruby rubyonrails ramaze stories glassfish

Tuesday May 05, 2009

Rails Conf 2009 Day 2 Trip Report

This is a follow up post from David's keynote.

Attended Women in Rails panel discussion. The panel, Sarah Mei, Lori Olson, and Desi McAdam (from L to R), had a very interesting discussion around the genuine problems and possible solutions of involving more women in Rails community.

Sarah is trying to involve more women in the San Francisco Ruby meetup. She plans to invite non-traditional audience like those who never programmed before, other language programmers, and similar. The details will be shared after performing the exercise for a year. Lori started Calgary Ruby Group. She do lot of self promotion so that younger women feel inspired. Desi is a co-founder of devChix with the purpose of "build a community of women developers". All the panelists were very vocal about being visible, having a blog and twitter presence is a good start.

Here are some random notes captured ...

Women drop out because of kids, try to get a job and then come back with a gap in the resume. It's difficult to get a new job at that time. Sarah is trying to reach out to that group who have that gap in their resume.

Visbility is important "She did that, I can do too!".

Data point: Women % in Rails community is much less than in other development community, e.g. Java or .NET world.
Another data point: % of women is more in larger companies, not in smaller companies. The reason is facilities like maternity leave, training (don't have evening hours to train themselves, can't sacrifice family time), etc.

Real stats from 2006: Women participation in open source community is 2-3%, 20-25% in "enterprise"

Appeal from the panelist "Guys, help us, tell .NET developer that Rails is not all guys, spread the word.".

Here are some Q&As captured:

Q. Should women be given free/discounted tickets to RailsConf ?
A. If women can't pay for it, then devChix can help them. RailsConf have helped before. It'll help if childcare is available.

Q. Why are we only looking at CS ? Why not other areas who have the development skills ?
A. Panel do reach out to multiple audience and seeks help from everybody in spreading the word. Women will be working on JavaScript and thinks she is designer. A guy will read 3 blog entries and thinks he is developer. There is a market salary differential between designer and developer. Women need to be more public about their programming status.

Q. Women won't present themselves as something they are not confident because they'll be called upon. How do you fix it ?
A. Everybody is learning. David's comment "I don't know everything in Rails" was commended. Girls need to know if it's important then they can figure it out. They are scared of messing the impression of their gender.

And of course there was a discussion on "Pr0ngate scandal":

Sarah: Matt is not a bad guy, he made a mistake that lot of people make in software development. If 1 out of 100 does not match the pattern of software developer, then that "1" may not be a software developer. The organizers of the conference did not do anything wrong. I voted for the talk and trust the judgement of the people. A negative feeling started developing but don't want to see that honestly. We learned something from it. As a relatively young community, this was bound to happen.

Lori: Not from the presentation itself but form the community reaction to this event. Blown out of proportion because of the same reasons when there is a conflict with developers in same company. You can't argue with somebody regarding how they feel. Can have a discussion, but argument is never going to be a win for anyone. That's where the community reaction devolved.

Desi: If Matt would've said "Oh Crap, I offended and wouldnt mean to offend you.", everything would've been fine. To David: "Next time, do us a favor and keep your mouth shut. It didn't help."

I was certainly expecting many more women to show up in the room but there were very few. Anyway, read Desi's blog entry about the panel. And I reached out to all three of them for helping in any manner :)

I presented on Develop with Pleasure, Deploy with Fun: GlassFish and NetBeans for a better Rails experience, slides here. The several concepts in the talk are explained in the following bullets:

The next talk of the day was JRuby: State of the Art

Why JRuby on VM ?
  • Best memory management
  • Dynamic optimizations
  • Reliable native threads: run threads across multiple cores
  • Vast number of libraries
  • Interop with Java, Scala, Rhino, Jython, ...
  • Ubiquitous
  • Fastest production-ready Ruby implementation
  • Definitely faster than 1.8.6
  • JRuby -> Bytecode -> Native code -> Optimizations
Future JVM Work
  • "invokedynamic": Build fast dynamic invocation in JVM, JRuby support by June, allow Hotspot to do all optimizations across Ruby calls
  • Multi-language VM "Da Vinci Machine", Optimized tail calls, continuations, fixnums, value types
  • Only production-ready impl with real threads
  • Ruby thread is a normal thread that can run on multiple cores
Simple Rails App
  • 1 Controller/Mode/View, send 1000 reqs
  • 80% less memory in 10 instance example, 96% for 20 instances
  • Gem, WAR-based
  • nginx, Apache: mod_proxy
Ruby 1.9 is 80-90% complete, IRB works, RubyGems works

  • Call C functions directly from Ruby
  • Portable unlike extensions
Who uses JRuby ?
  • Kenai
  • Gravitor
  • King Pong (JRuby wrapping MonkeyEngine)
  • Oslo's Gardermoen Airport to refuel planes
  • ThoughtWorks Mingle
    • No cross-platform SVN libraryfor Ruby
    • Bundling of installation
    • Security (ecnrypting source code)
    • Memory profile
    • Avoiding process proliferation
    • 5 developers, 6 weeks for all development, 2887 LOC
  • Trisano: Open source infectious disease reporting system
    • Ease of deployment
    • Every enterprise on the planet run Java
    • Extensive project roadmap
Check out interactive Q & A from the session in the following video fragment:

<script type="text/javascript" src=""></script> <script type="text/javascript" src=""></script>

Later in the evening, Brian Helmkamp, Aman Gupta, Luis Navena, Pat Allan, Dan Kubb, and John Nunemaker were awarded Ruby Heroes Award!

And the keynote by Tim Ferris, lets not talk about it ;-) I edited pictures, authored my blog, caught up on email/RSS during the keynote. #railconf on IRC and twitter were way more fun! Check the live ratings.

"1" was the lowest rating that could be given anyway!

Watch the interview on why Sea Change Affinity picked JRuby/GlassFish.

Finally watch some of the snapshots captured today:

And then the evolving album:

Technorati: conf railsconf lasvegas jruby rubyonrails glassfish netbeans

Sea Change Affinity - Why JRuby/GlassFish ?

At Rails Conf 2009, Jay McGaffigan from Sea Change talked about why they choose JRuby/GlassFish for their product Affinity. Here are some of the reasons he quoted:
  • Performance characterisitics (of GlassFish) have been excellent
  • Picked GlassFish based upon the recommendations from the people in industry
  • Dramatically more throughput on our GlassFish installation, 400 requests/sec instead of 100 requests/sec comapred to Tomcat
Watch the interview recorded earlier today:

Read other simiar stories at glassfish+rubyonrails+stories.

Technorati: jruby rubyonrails glassfish stories

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.

Java EE 7 Samples

Stay Connected


« July 2016