Skip to main content

Rails and Java EE integration - Servlet co-bundled and invoked from Rails

Posted by arungupta on April 4, 2008 at 8:04 AM PDT

One of the href="http://developers.sun.com/appserver/reference/techart/rails_gf/#advantages">several
advantages of deploying Rails
applications on GlassFish
is - co-hosting Rails and Java EE applications in the same container.
The href="http://blogs.sun.com/arungupta/entry/screencast_web_9_jruby_on">screencast
#web9 shows how Rails applications can be easily deployed on
GlassFish.



This blog takes the JRuby-on-Rails (jRoR) and Java EE integration to
the next level. It show how a Java EE Servlet can be co-bundled within
a jRoR application. And then it shows how such a servlet can be easily
invoked from a Rails view. It uses href="http://developers.sun.com/appserver/reference/techart/rails_gf/#deploying">WAR-based
mode for deploying jRoR applications on GlassFish.



Here are the detailed steps:

  1. In an existing JRuby
    1.1 RC3
    installation (enabled with Rails), install the
    required gems:


    cellpadding="2" cellspacing="2">
    ~/testbed/jruby-1.1RC3
    >bin/jruby -S gem
    install
    activerecord-jdbc-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.8

    1 gem installed

    Installing ri documentation for activerecord-jdbc-adapter-0.8...

    Installing RDoc documentation for activerecord-jdbc-adapter-0.8...
  2. Create a Rails app as:


    cellpadding="2" cellspacing="2">
    ~/testbed/jruby-1.1RC3/samples/rails > style="font-weight: bold;">../../bin/jruby -S rails
    railsee1

          create 

          create 
    app/controllers

          create 
    app/helpers

          create 
    app/models

          create 
    app/views/layouts

          create 
    config/environments

          create 
    config/initializers

          create  db

          create  doc

          create  lib

          create 
    lib/tasks

          create  log

          create 
    public/images

          create 
    public/javascripts

          create 
    public/stylesheets

          create 
    script/performance

          create 
    script/process

          create 
    test/fixtures

          create 
    test/functional

          create 
    test/integration

          create 
    test/mocks/development

          create 
    test/mocks/test

          create 
    test/unit

          create 
    vendor

          create 
    vendor/plugins

          create 
    tmp/sessions

          create 
    tmp/sockets

          create 
    tmp/cache

          create 
    tmp/pids

          create 
    Rakefile

          create 
    README

          create 
    app/controllers/application.rb

          create 
    app/helpers/application_helper.rb

          create 
    test/test_helper.rb

          create 
    config/database.yml

          create 
    config/routes.rb

          create 
    public/.htaccess

          create 
    config/initializers/inflections.rb

          create 
    config/initializers/mime_types.rb

          create 
    config/boot.rb

          create 
    config/environment.rb

          create 
    config/environments/production.rb

          create 
    config/environments/development.rb

          create 
    config/environments/test.rb

          create 
    script/about

          create 
    script/console

          create 
    script/destroy

          create 
    script/generate

          create 
    script/performance/benchmarker

          create 
    script/performance/profiler

          create 
    script/performance/request

          create 
    script/process/reaper

          create 
    script/process/spawner

          create 
    script/process/inspector

          create 
    script/runner

          create 
    script/server

          create 
    script/plugin

          create 
    public/dispatch.rb

          create 
    public/dispatch.cgi

          create 
    public/dispatch.fcgi

          create 
    public/404.html

          create 
    public/422.html

          create 
    public/500.html

          create 
    public/index.html

          create 
    public/favicon.ico

          create 
    public/robots.txt

          create 
    public/images/rails.png

          create 
    public/javascripts/prototype.js

          create 
    public/javascripts/effects.js

          create 
    public/javascripts/dragdrop.js

          create 
    public/javascripts/controls.js

          create 
    public/javascripts/application.js

          create 
    doc/README_FOR_APP

          create 
    log/server.log

          create 
    log/production.log

          create 
    log/development.log

          create 
    log/test.log
  3. Install Goldspike plugin in the application as:


    cellpadding="2" cellspacing="2">
    ~/testbed/jruby-1.1RC3/samples/rails/railsee1
    >../../../bin/jruby
    script/plugin install
    svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike


    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/test

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/test/war_config_test_config.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/test/test_java_library.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/test/test_maven_library.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/test/test_create_war.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/Rakefile

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/init.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/tasks

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/tasks/war.rake

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/util.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/war_config.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/run.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/java_library.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/packer.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/lib/create_war.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/install.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators/goldspike

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators/goldspike/goldspike_generator.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators/goldspike/templates

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators/goldspike/templates/web.xml.erb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/generators/goldspike/templates/war.rb

    A   
    /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1/vendor/plugins/goldspike/README

    Exported revision 960.

          exists 
    config

          create 
    config/war.rb

          create 
    WEB-INF

          create 
    WEB-INF/web.xml.erb



    Optionally href="http://blog.nicksieger.com/articles/2007/09/04/warbler-a-little-birdie-to-introduce-your-rails-app-to-java">Warbler
    may be used for packaging and Goldspike for dispatching.

  4. Create a Java library with Servlet code
    1. Using NetBeans IDE, create a project of type "Java Class
      Library" and
      specify the name "HelloServlet".
    2. Right-click on the project, select "New" and
      "Servlet...". Enter the
      class name as "HelloServlet" and package as "server" as shown below:



      src="http://blogs.sun.com/arungupta/resource/ror/railsee-helloworld-servlet.png">
    3. Right-click on the project, select Properties and in
      "Libraries", "Compile Tab Libraries" add
      "javaee.jar" from href="https://glassfish.dev.java.net/downloads/v2ur1-b09d.html">GlassFish
      v2 UR1 "lib" directory.
    4. Change the "try" block in "processRequest" method to
      following:


      cellpadding="2" cellspacing="2">
      String
      name = request.getParameter("name");

      if (name == null || name.equals(""))

          name = "Duke";

                 


      out.println("<h1>Servlet HelloServlet at " +
      request.getContextPath () + " says Hello " + name +
      "!</h1>");
    5. Right-click on the project and select "Clean and Build".
  5. Configure Rails app for Servlet
    1. In your Rails application directory, add the following
      fragments to "WEB-INF/web.xml.erb":


      cellpadding="2" cellspacing="2">
      <servlet>

                     
      <servlet-name>hello</servlet-name>

                     
      <servlet-class>server.HelloServlet</servlet-class>

      </servlet>


      cellpadding="2" cellspacing="2">
      <servlet-mapping>

                     
      <servlet-name>hello</servlet-name>

                     
      <url-pattern>/hello</url-pattern>

      </servlet-mapping>
    2. Create "WEB-INF/lib" directory and copy
      "HelloServlet.jar" from the "dist" directory of NetBeans project here.
  6. Create & Deploy the WAR
    1. Create a WAR file as:


      cellpadding="2" cellspacing="2">
      ~/testbed/jruby-1.1RC3/samples/rails/railsee1
      >../../../bin/jruby
      -S rake war:standalone:create


      (in
      /Users/arungupta/testbed/jruby-1.1RC3/samples/rails/railsee1)

      info: Assembling web application

      info: Packing needed Java libraries ...

      info:   adding Java library jruby-complete-1.1RC3

      info:   adding Java library goldspike-1.6

      info:   adding Java library activation-1.1

      info:   adding Java library commons-pool-1.3

      info:   adding Java library bcprov-jdk14-124

      info: Packing needed Ruby gems ...

      info:   adding Ruby gem rails version 2.0.2

      info:   adding Ruby gem rake version 0.8.1

      info:   adding Ruby gem activesupport version 2.0.2

      info:   adding Ruby gem activerecord version 2.0.2

      info:   adding Ruby gem actionpack version 2.0.2

      info:   adding Ruby gem actionmailer version 2.0.2

      info:   adding Ruby gem activeresource version 2.0.2

      info:   adding Ruby gem activerecord-jdbc-adapter
      version 0.8

      info: Packing needed files ...

      info: Creating web archive
    2. Deploy the WAR to href="https://glassfish.dev.java.net/downloads/v2ur1-b09d.html">GlassFish
      v2 UR1 as:


      cellpadding="2" cellspacing="2">
      ~/testbed/jruby-1.1RC3/samples/rails/railsee1
      >~/testbed/glassfish/v2ur1/glassfish/bin/asadmin
      deploy railsee1.war


      Command deploy executed successfully.
  7. The bundled Servlet is now accessible at
    "http://localhost:8080/railsee1/hello". The default browser output
    looks like:



    src="http://blogs.sun.com/arungupta/resource/ror/railsee-helloworld-servlet-default-output.png">



    And passing a parameter to the URL as
    "http://localhost:8080/railsee1/hello?name=Arun" shows the output as:



    src="http://blogs.sun.com/arungupta/resource/ror/railsee-helloworld-servlet-custom-output.png">
  8. With this, your Java EE Servlet is now bundled with your Rails
    application deployed on GlassFish v2 UR1.



    Now, lets add Controller and View to Rails application and invoke this
    servlet from there to show complete integration with Rails.

  1. Create a new Controller and View as


    cellpadding="2" cellspacing="2">
    ~/testbed/jruby-1.1RC3/samples/rails/railsee1
    >../../../bin/jruby
    script/generate controller home index


    JRuby limited openssl loaded. gem install jruby-openssl for full
    support.

    http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL

          exists 
    app/controllers/

          exists 
    app/helpers/

          create 
    app/views/home

          exists 
    test/functional/

          create 
    app/controllers/home_controller.rb

          create 
    test/functional/home_controller_test.rb

          create 
    app/helpers/home_helper.rb

          create 
    app/views/home/index.html.erb
  2. Change the generated controller in
    "app/controllers/home_controller.rb" to:


    cellpadding="2" cellspacing="2">
    class
    HomeController < ApplicationController



    include Java



      def index

           
    url = java.net.URL.new("http://localhost:8080/railsee1/hello");

           
    conn = url.open_connection;

           
    reader =
    java.io.BufferedReader.new(java.io.InputStreamReader.new(conn.get_input_stream));

           
    @servlet_output = "";

           
    input_line = reader.read_line;

           
    while input_line != nil

                   
    @servlet_output << input_line;

                   
    input_line = reader.read_line;

           
    end

           
    reader.close;

      end

    end
  3. Change the generated view in
    "app/views/home/index.rhtml.erb" to:


    cellpadding="2" cellspacing="2">
    <h1>Home#index</h1>

    <p>Find me in
    app/views/home/index.html.erb</p>



    <%= @servlet_output %>
  4. Re-create & re-deploy the WAR as describd in bullet
    # 6 above. And
    now
    "http://localhost:8080/railsee1/home/index" shows the output as shown:



    src="http://blogs.sun.com/arungupta/resource/ror/rails-helloworld-servlet-view-output.png">

This shows how a Java EE 5 Servlet can be easily invoked from a Rails
application deployed on GlassFish. JRuby-on-Rails and GlassFish allows
you to leverage business knowledge that exists in Java EE applications
very easily and still providing Rails agility.





Technorati: href="http://technorati.com/tags/rubyonrails">rubyonrails
netbeans
glassfish
javaee5
servlets
jruby
ruby
goldspike

Related Topics >>