Monday, September 28, 2009

Problem with Warbler

While I was building the war/ear file I was facing problem at the building time as well as after deployment. Here I tried to mention all those problems:

1) Warbler doesn't copy .specifications file: When we execute gems:unpack:dependencies it creates .specifications file for each gem in your vendor/gems folder. Then when we execute 'war' task it doesn't copy this file into the war file. I solved this problem by adding following line in the config/warble.rb file

config.includes = FileList["vendor/gems/*/.specification"]

2) I was getting Don't know how to build task '' when log folder was there: This is something wired I got when I added the gem 'composite_primary_keys'. There are two solutions for this
  • rename the log folder to some other name and then execute the war task
  • in your warble.rb file use config.gems = []
3) After deployment I was getting undefined method `new' for "Rack::Lock":String: After googling I came to following solution
  • download jruby-complete-1.3.1.jar from here in lib folder
  • download jruby-rack-0.9.5-20090625.190033-5.jar from here in lib folder
  • in config/warble.rb file add following lines
    config.java_libs.delete_if {|f| f =~ /jruby-rack/ || f =~ /jruby-complete/ }
    config.java_libs += FileList["lib/*.jar"]
4) Cannot load gem at [SYSTEM_JRUBY_CACHE_PATH] in MY_APP_FOLDER: I was getting this error when I started using 'composite_primary_keys' gem and trying to execute the war task by jruby rake. The version of this jruby rake is 0.8.7. After some analysis and testing with different version of rake I have identified that if I use older rake (version less then 0.8.4) then the problem is gone. Other thing that you can do is in your warble.rb file use config.gems = []
Some helpful links:

http://kenai.com/jira/browse/JRUBY_RACK-18
http://stufftohelpyouout.blogspot.com/2009/06/how-to-get-warbler-to-include-custom.html
http://stufftohelpyouout.blogspot.com/2009/07/fix-ioerrorio-errorbroken-pipestrange.html
http://wiki.oracle.com/thread/3104945/Error+during+jruby-rack+initialization

Friday, September 25, 2009

JRuby on Rails building with warbler

Here I will mention the steps to create a JRuby (v1.3.1) on Rails (v2.3.3) application and build the war file using Warbler (v0.9.13) gem and then deploy in the JBoss (4.2.3.GA).

See my previous blog Oracle with JRuby using activerecord-jdbc-adapter to install JRuby, Rails and activerecord-jdbc-adapter to

In real life we need to work with gems & plugins for that reason I will now install some gems and plugins. jruby-openssl is required because if you don't install it then you will get JRuby limited openssl loaded. gem install jruby-openssl for full support

- JRUBY_HOME\bin\jruby -S gem install jruby-openssl
- JRUBY_HOME\bin\jruby -S gem install mislav-will_paginate
- install wee_date_picker plugin. To see the installation instruction see http://github.com/pyrat/wee_date_picker

Now create a rails project and in the environment.rb file add followings:

#config all the gems used with this project
config.gem "activerecord-jdbc-adapter", :version => '0.8', :lib => 'jdbc_adapter'
config.gem "jruby-openssl", :version => "0.5.1", :lib => 'openssl'
config.gem 'mislav-will_paginate', :version => '~> 2.3.11', :lib => 'will_paginate', :source => 'http://gems.github.com'
I like to configure my rails app to use gems and rails that are in the vendor folder. To make all the used gems copied to vendor/gems folder execute following rake task:

RAILS_APP_HOME>JRUBY_HOME\bin\rake gems:unpack:dependencies
To freeze rails with my application execute following rake task:
RAILS_APP_HOME>JRUBY_HOME\bin\rake rails:freeze:gems

Now its time to think about building the war/ear file to deploy in JBoss. As I have already said to build the war file I use Warbler. To do that install the gem:

JRUBY_HOME\bin\jruby -S gem install warbler

Its convenient to have warbler as plugins in your application and to make the plugin use following command and then you will have the warbler plugin in your vendor/plugins folder:

JRUBY_HOME\bin\warble pluginize

To customize files, libraries, and gems included in the.war file, you'll need a config/warble.rb file. As you have already created the warble plugin you can execute following to create warble.rb file for you:

RAILS_APP_HOME>JRUBY_HOME\bin\jruby script/generate warble
Now its time to create the war file of your project. To do that execute following rake task:

RAILS_APP_HOME>JRUBY_HOME\bin\rake war
At this point everything should be done but in my case I faced couple of problems. If you face problem please see my next blog 'Problem with Warbler'

Thursday, September 24, 2009

Configure Log4j with JRuby on Rails for JBoss

Its very easy to use any Java library from you JRuby code. In one of my JRuby on Rails project I had to use two different logger for logging purpose. One is the Rails default logger for all jruby code and other is log4j logger that is for my java codes and libraries. To use both of the logger I made following changes.

At first I added mylog4j.properties and log4j-1.2.15.jar in my project's lib folder. By default the ruby log file goes to log folder. If we want to keep this log file in this default folder then we don't need to change anything. A sample mylog4j.properties file content is given here:

log4j.rootLogger=DEBUG, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=[%d{ISO8601}] %-5p (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/opt/jboss/server/default/log/myapp_rails.log


log4j.appender.R.MaxFileSize=10000KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}] %-5p (%F:%L) - %m%n

log4j.logger.org.apache.commons.digester=WARN
log4j.logger.org.apache.commons.beanutils=WARN
log4j.logger.org.apache.commons.validator=WARN
log4j.logger.org.apache.commons.httpclient=DEBUG

log4j.logger.org.springframework=DEBUG

In my case I developed a JRuby on Rails application that was deployed in JBoss server. Thats why I decided not to use the default log folder of Rails application for log files rather use the JBoss log folder to store the log files.
For that reason I need to know the log folder path of JBoss in my environment.rb file and then change the log file path that will be used by Rails. You can get the JBoss log folder path by:

java.lang.System.getProperty('jboss.server.log.dir')

So the corresponding changes in environment.rb file that I made are:

jboss_server_log_dir = java.lang.System.getProperty('jboss.server.log.dir')
if jboss_server_log_dir
config.log_path = File.join(jboss_server_log_dir,'frengine_admin.log') if (jboss_server_log_dir && !jboss_server_log_dir.strip.empty?)
end

config.logger = Logger.new(config.log_path, 50, 1048576)

And to specify the same log folder in the mylog4j.properties file I used following line:

log4j.appender.R.File=${jboss.server.log.dir}/myapp_java.log

Now you will be able to see two different log file in the JBoss log folder. If you want to use same log file for all kind of logging use single file name.

Wednesday, September 23, 2009

JRuby on Rails: using JDBC driver

In JRuby world the bridge between Rails activerecord and JDBC driver is activerecord-jdbc-adapter. activerecord-jdbc-adapter allows you to use virtually any JDBC-compliant database with your JRuby on Rails application. You can verify the supported JDBC-compliant database by going to JRUBY_HOME\lib\ruby\gems\1.8\gems\activerecord-jdbc-adapter-0.8\lib\active_record\connection_adapters. For every supported database you will have databasename_adapter.rb file. Please see my blog 'Oracle with JRuby using activerecord-jdbc-adapter' to install JRuby, Rails and activerecord-jdbc-adapter and test your installation is correct.

Now its time to configure the database.yml file. Since version 2.0 Rails automatically look for and load an adapter gem based on the name of the adapter you specify in database.yml. Example:

development:
adapter: jdbc
...

With this database configuration, Rails will attempt to load the activerecord-jdbc-adapter gem. Here is an example for oracle database:

development:
adapter: oracle
driver: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@localhost:1521:XE
username: username
password: password

If you want to work with the connection itself then require the active_record/connection_adapters/jdbc_adapter library and call the method ActiveRecord::Base.jdbc_connection in order to obtain a connection to the database:

require 'rubygems'
require 'active_record'
require 'active_record/connection_adapters/oracle_adapter'

ActiveRecord::Base.jdbc_connection

In upcoming blog I am going to write on using JNDI in your JRuby on Rails application and deploying in JBoss.

Monday, September 21, 2009

Oracle with JRuby using activerecord-jdbc-adapter

  • Download jruby from http://dist.codehaus.org/jruby/1.3.1/ and install it. For convenience you can set an environment variable JRUBY_HOME = C:\jruby-bin-1.3.1\ (/opt/jruby-1.3.1 for linux/OSX) and optionally you can add this environment variable to the PATH variable.

    set PATH=%PATH%;JRUBY_HOME (windows)
    export PATH=$PATH:JRUBY_HOME (linux or OSX)


  • install rails using jruby -S gem install -y rails (in my time the latest one was 2.3.3)
    If you didn't set the environment varilable in the path variable then you will have to execute following command:
    JRUBY_HOME\jruby -S gem install -y rails
    If you want to specify version then
    jruby -S gem install -y rails --version 2.3.3
  • install activerecord-jdbc-adapter (version - 0.8) using
    jruby -S gem install -y activerecord-jdbc-adapter --version 0.8 or
    JRUBY_HOME\jruby -S gem install -y activerecord-jdbc-adapter --version 0.8

    At first I installed the newer version 0.9.1 but with that version I was getting following error for timestamp type column: "undefined method 'new_date' for JdbcSpec::Oracle::Column:Module". I have a plan to solve this problem later
  • Now its time to test activerecord, activerecord-jdbc-adapter, jdbc-driver from jirb. To test we need couple of tables in the database. Lets say we have two tables:
    - authors
    - articles [an author can have multiple articles]
  • Now copy the oracle-jdbc-driver jar file (ojdbc14-10.2.0.1.0.jar) in the JRUBY_HOME\lib folder then run 'jirb'. To run "jirb" in command prompt go to JRUBY_HOME\bin and type 'jirb'. Now in the 'irb' console type followings:

    require 'rubygems'
    require 'active_record'
    require 'active_record/connection_adapters/oracle_adapter'

    class Author < adapter =""> 'jdbc',
    :driver => 'oracle.jdbc.driver.OracleDriver',
    :url => 'jdbc:oracle:thin:@localhost:1521:XE',
    :username => 'username',
    :password => 'password')

    Author.all()
Here you go !! You are done !!

Some useful links: