Deploying JRuby application on Tomcat, Glassfish and Websphere 6.1
This article is a continuation from the topic about Installing JRuby and JRuby on Rails with MySQL.
Here I am going to talk about how to deploy the application in a Java Application Server. We’re going to use Tomcat, Glassfish and IBM Websphere 6.1.
First of all, we have to learn how to package our JRuby application in a WAR file.
Packaging the application in a WAR file
So far we have installed JRuby, JRuby on Rails, created an application, setup the JDBC adapter and created a scaffold application. However the principal idea of JRuby is use it with Java application, therefore a good thing to do is generate a WAR file and deploy a JRuby application into Java Application Server (like Glassfish, Tomcat or Websphere).
Fortunately there is an easy way to create a war file from a JRuby application. We must use a gem called warbler. It is responsible to create the WAR file, package all the JRuby code, provide the web.xml, as well as a servlet to manage the requests.
Installing Warbler
Type the following:
jruby -S gem install warblerUsing Warbler
Inside the application directory, type the following code to generate the config/warble.rb file.
jruby -S warble configNow, edit the warble.rb file and change the following:
# config.gems = ["activerecord-jdbc-adapter", "jruby-openssl"]to
config.gems = ["activerecord-jdbc-adapter"]
Why do it? Because the warble doesn’t import the jdbc-adapter to the WAR file, in this way, when you try to run the WAR in a Java Application Server, you will get exception. If you uncomment the line above, then warble will import the jdbc-adapter and everything will run without problem.
Also, if you want, you can change the line:
config.webxml.rails.env = 'production'
to
config.webxml.rails.env = 'development'
Save the file and now it is time to generate the WAR file. Simply type the following:
jruby -S warbleIt’s done. Now it is time to deploy that war file in a Java Application Server.
Deploying JRuby on Rails application on Tomcat
If you do not have Tomcat installed yet, you can check this link.
To deploy our JRuby application on Tomcat is straightforward. Simply copy the war file to $TOMCAT_HOME/webapps directory.
After that starts tomcat and open the following link: http://localhost:8080/jrubytest/products
Deployment JRuby on Rails application on Glassfish
You can use the same .war file used on Tomcat to be deployed on Glassfish.
First of all, you must start Glassfish and open its Admin Console: http://localhost:4848/login.jsf.
There go to the Web Applications section, under Applications. On new screen, click on Deploy button.
Choose the jrubytest.war file and click on OK. Done!, the JRuby on Rails application was deployed.
Run the application through the link: http://localhost:8080/jrubytest/products
Deployment JRuby on Rails application on Websphere Application Server 6.1.
Websphere complains the web.xml file built by warble, because of this we need to change the default web.xml file format.
To do that, go to the warble directory, in my case, /usr/lib/jruby-1.1.2/lib/ruby/gems/1.8/gems/warbler-0.9.9 and change the web.xml.erb file.
The original is:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <% webxml.context_params.each do |k,v| %> <context-param> <param-name><%= k %></param-name> <param-value><%= v %></param-value> </context-param> <% end %> <filter> <filter-name>RackFilter</filter-name> <filter-class>org.jruby.rack.RackFilter</filter-class> </filter> <filter-mapping> <filter-name>RackFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class><%= webxml.servlet_context_listener %></listener-class> </listener> <% if webxml.jndi then webxml.jndi.each do |jndi| %> <resource-ref> <res-ref-name><%= jndi %></res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <% end; end %> </web-app>
to
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <% webxml.context_params.each do |k,v| %> <context-param> <param-name><%= k %></param-name> <param-value><%= v %></param-value> </context-param> <% end %> <listener> <listener-class><%= webxml.servlet_context_listener %></listener-class> </listener> <servlet> <servlet-name>Rails</servlet-name> <servlet-class>org.jruby.rack.RackServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Rails</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <% if webxml.jndi then webxml.jndi.each do |jndi| %> <resource-ref> <res-ref-name><%= jndi %></res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <% end; end %> </web-app>
After that, go to the jrubytest directory and build the war file again. jruby -S warble. It’s done, now you’ve got a war file complaint with Websphere environment.
Deploy the war file on Websphere and try to run the application through the link: http://localhost:9080/jrubytest/products
The article overs here. I hope this article, as well as the previous article be useful for anyone.



Brazilian guy, IT Specialist, Linux User, IBM Certified SOA Fundamentals, Rational Developer, Sun Certified Java Associate 1.0, Sun Certified Java Programmer 1.4, Sun Certified Web Component Developer 1.4 and Sun Certified Business Component Developer 5. Also Ruby and Python enthusiastic.
Nice Article Jair! Just a tip in case of deploying in WAS you can make a copy of the file web.xml.erb in your app/config directory and make the changes in this file instead of the file of warbler gems. When running warble command it will verify the file exists in your config directory and will use it. Regards, Leonardo
Hey Léo.
Thanks for the tip. I didn’t know that :). After your lecture at IBM I started my studies in JRuby and I found the problem with WAS. Looking at google I found the tip but yours is much better :).
Hi, everything works as expected until I try to deploy to app server. I have tried both Tomcat and Glassfish and get very similar errors. Below is the relevant log entry…any ideas?
[#|2008-10-01T20:38:17.034-0600|SEVERE|sun-appserver9.1|javax.enterprise.system.container.web|_ThreadID=16;_ThreadName=httpSSLWorkerThread-8080-0;_RequestID=3c224ae4-03a6-4b65-92c3-efcb8b7d862a;|WebModule[/jrubytest]Exception caught
org.jruby.rack.RackInitializationException: exit
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:38:in `run’
from /Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails_boot.rb:20:in `run’
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:11:in `boot!’
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:109
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:11:in `require’
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/environment.rb:11
from /Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/environment.rb:29:in `load’
from /Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails.rb:29:in `load_environment’
from /Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails.rb:152:in `new’
from :3
from /Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/rack/builder.rb:22:in `instance_eval’
from /Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/rack/builder.rb:22:in `initialize’
from :3
at org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:154)
at org.jruby.rack.DefaultRackApplicationFactory.getApplication(DefaultRackApplicationFactory.java:53)
at org.jruby.rack.PoolingRackApplicationFactory.getApplication(PoolingRackApplicationFactory.java:92)
at org.jruby.rack.DefaultRackDispatcher.process(DefaultRackDispatcher.java:31)
at org.jruby.rack.RackFilter.doFilter(RackFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:198)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:288)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.jruby.exceptions.RaiseException
at Rails::GemBoot.load_rails_gem(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:53)
at Rails::GemBoot.load_initializer(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:38)
at Rails::Boot.run(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails_boot.rb:20)
at Rails::BootHook.run(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:11)
at #.boot!(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:109)
at (unknown).(unknown)(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/boot.rb:11)
at Kernel.require(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/environment.rb:11)
at (unknown).(unknown)(/Users/Mike/glassfish/domains/domain1/applications/j2ee-modules/jrubytest/WEB-INF/config/environment.rb:29)
at Kernel.load(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails.rb:29)
at JRuby::Rack::RailsServletHelper.load_environment(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/jruby/rack/rails.rb:152)
at #.new(:3)
at (unknown).(unknown)(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/rack/builder.rb:22)
at Kernel.instance_eval(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/rack/builder.rb:22)
at Kernel.instance_eval(/Users/Mike/glassfish/domains/domain1/generated/jsp/j2ee-modules/jrubytest/loader/rack/builder.rb:22)
at Rack::Builder.initialize(:3)
at (unknown).(unknown)(:1)
|#]