天天看點

Run a RoR application with JRuby and OC4J 10.1.3

I’m currently preparing the deployment of our RoR application (a kind of portal for our enterprise) in Oracle App Server 10g.

Our application is currently deployed under Litespeed Web Server, running with Ruby MRI: we encounter some problems of performances with Database connections and we also have some bunch of Ruby code that are a port of Java Libraries from Oracle. We also need to have a better integration with the Oracle Single Sign On Server, and with the Oracle Content Db.

By using the JRuby environment , we’ll be able to reuse original Oracle Java libraires from our application. We’ll check also performances and memory load before using it in production.

Before moving to the App Server 10g, i need to test it before in an OC4J standalone 10.1.3 (same release of the J2EE container), with JDK 5 , 32 bits (as our Java setup on the Linux server).

For this i started from Oracle AppLabs Wiki article

Prerequisities :

- Linux ( i currently use a Fedora Core 7 on my development desktop, and our Server is setup with a Suse 9)

- JDK 5

- JRuby 1.1

- Rails 1.2.5 / 2.1 (we currently have our RoR application written for Rails 1.2.5 - we plan later to upgrade to Rails 2.1 by reviewing the code for deprecations)

- activerecord-jdbc-adapter 0.8.0

- Oracle JDBC Driver (depending on your database release; if 10g use ojdbc14.jar , if 11g use ojdbc5.jar )

- Warbler

- Oracle Database 10g XE / Oracle Database 10g EE or SE / Oracle Database 11g

- Oracle Containers for J2EE (OC4J) 10gR3

First download Jdk 5 for your platform and JRuby 1.1

Set Environment variables : JAVA_HOME, JRUBY_HOME

Add $JAVA_HOME/bin and $JRUBY_HOME/bin in the $PATH

Set env. CLASSPATH with $JRUBY_HOME/lib and $JAVA_HOME/lib

Install Rails 1.2.5 :

sudo jruby -S gem install rails –version=1.2.5

Install Rails 2.1 :

sudo jruby -S gem install rails –version=2.1

Install activerecord-jdbc-adapter :

sudo jruby -S gem install activerecord-jdbc-adapter

Download the Oracle JDBC Driver (ojdbc14.jar for JDK 5 and Database 10g, or ojdbc5.jar for JDK 5 and Database 11g, or even ojdbc6.jar if JDK 6 is used with Oracle Database 11g)

Copy the JAR in your $JRUBY_HOME/lib

Note: “JRuby leverages JDBC to access various JDBC compliant database systems and Ruby-OCI8 can’t work with JRuby because “Many Gems will work fine in JRuby however some Gems build native C libraries as part of their install process. These Gems will not work in JRuby unless the Gem has also provided a Java equivalent to the native library.” as stated in the JRuby Wiki . The latest ActiveRecord JDBC Adapter (v0.8.0) only works with JRuby 1.1RC3 or future version.”

Run a Rails application

To generate your application from scratch, launch the command :

jruby -S rails <app_name>

In my case, i just want to see if one of our applications we developed recently could run easily .

For this i do a checkout against our SVN repository : i get the source code in my Working copy. The application has been done for Rails 1.2.5. It’s an application mimicking the http://www.yousendit.com web application .

First i changed the line in config/environment.rb

RAILS_GEM_VERSION = ‘2.1.0′ unless defined? RAILS_GEM_VERSION

Add the following lines after “Rails::Initializer.run do |config|” :

config.action_controller.session = {

:session_key => ‘_sharails_session’,

:secret => ‘643c1821df270a8662a2e011836996053a3241eea164d81e18a9314c0a39ea68f6c20027e3c4d41309469

38acc6e164912fa3331747c8b5f0c2f0de6adbb7332′

}

Modify config/database.yml :

I should configure my connection as is in the database.yml file :

common: &shared

adapter: jdbc

driver: oracle.jdbc.driver.OracleDriver

url: jdbc:oracle:thin:@<hostname>:<port>:<sid>

username: railsuser

password: railspasswd

development:

<<: *shared

production:

development

Then launch the rake db:migrate :

jruby -S rake db:migrate

Nota : In Rails 1.2, the jdbc adapter gem is not required by default by ActiveRecord. We need to add “jdbc” into $JRUBY_HOME/lib/ruby/gems/1.8/gems/activerecord-x.y.z/lib/active_record.rb as below:

unless defined?(RAILS_CONNECTION_ADAPTERS)

RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase frontbase jdbc )

end

First test with WebRick :

Launch the command :

jruby script/server

Then open the URL http://localhost:3000/sharails in your browser

I encounter several problems before to make it run in JRuby environment :

- Dates :

In our web form, we currently use a Javascript popup calendar, formatting dates in french format : dd/mm/yyyy (in Ruby , it would be %d/%m/%Y)

I should add an explicit data conversion in my action before saving (date_validite being a :date in migration script and DATE type in Oracle database) :

@document.validite_fin = Date.strptime(params[:document][:validite_fin] , ‘%d/%m/%Y’)

I also encountered problems when comparing @document.validite_fin with Date.today with minus operator - i should do the comparison between @document.validite_fin and Time.now

- msmtp :

I found the JRuby 1858 BugID in JIRA relating problems with IO.popen.

I should modify my config/environment.rb : (removed the complete path /usr/bin/msmtp)

IO.popen(”/usr/bin/msmtp …. replaced by IO.popen(”msmtp ….

I should modify my msmtp config file located in /etc/.msmtprc

“account gmail” replaced by “account default”

account default

host smtp.gmail.com

port 587

auth on

user <account>@gmail.com

password <pwd>

tls on

tls_starttls on

tls_trust_file /path/to/.certs/ThawtePremiumServerCA.crt

from <account>@gmail.com

logfile /path/to/msmtp.log

Finally , as tested with Rails 2.1 (and initially developed with Rails 1.2.5) , we previously used “render_without_layout” function, that is now deprecated . I should replace it by “render :layout => false”

Package the application with Warbler :

A recommended option is to use Warbler for packaging which provides a minimal, flexible and Ruby-like way to create WAR. Warbler really cleans up the packaging of WAR, for example excluding .svn directories, tests and migrations - really nice. For now, it uses RailsServlet for dispatching but even that is pluggable.

Install Warbler :

jruby -S gem install warbler

Generate the warbler configuration file :

jruby -S warble config

Edit config/warble.rb and add “activerecord-jdbc-adapter” , as Warbler doesn’t package automatically activerecord JDBC driver.

config.gems = ["activerecord-jdbc-adapter"]

# config.gems << “tzinfo”

config.gems["rails"] = “2.1.0″

Create the war file :

jruby -S warble

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

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

jar cf sharails.war -C tmp/war .

Deploy on OC4J standalone

OC4J stands for “Oracle Containers for J2EE”. OC4J standalone is the Oracle AS Containers for J2EE distribution which can be executed outside of the standard OracleAS environment. It is very easy to install(simply unzip it). Typically OC4J standalone would be used for development purposes and for small scale web solutions. OC4J 10g Standalone ships with Oracle JDBC driver for Java 1.4, so deploying JRuby on Rails application on it is made much easier:

Start OC4J :

cd $OC4J_ROOT/j2ee/home ; java -jar oc4j.jar

Then deploy your application :

- via the web console : http://localhost:8888/em

- by the command line :

a) For OC4J Standalone

java -jar $OC4J_ROOT/j2ee/home/admin_client.jar deployer:oc4j:localhost:23791 oc4jadmin -deploy \
-file /path/to/sharails.war -deploymentName sharails -bindAllWebApps      

Go to the following URL http://localhost:8888/sharails

b) For Oracle App Server 10g :

java -jar $ORACLE_HOME/j2ee/home/admin_client.jar deployer:oc4j:opmn://<hostname>:opmnPort/oc4jInstanceName \
 oc4jadmin <password> -deploy -file /path/<app_name>.war -deploymentName <


app_name




> -bindAllWebApps \
-contextRoot /

<contextRoot>






      

Go to the following URL http://hostname:7777/<contextRoot>

We got just some problems in some URLs that actually don’t include the web application context (sharails): it is the case for our download file URL, or some pictures set as background in our CSS files.

But everything works fine.

Other deployments available on JRuby Wiki