Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 

In his last blog posts krum.bakalsky explained how to build a JRuby on Rails application and run it on JPaaS.

Recently I worked with Krum to port a prototype we build on Ruby on Rails (RoR) to JPaaS using JRuby on Rails (JRoR). So today I'd like to share the process we used in the migrating. As we used this for prototyping only there are probably a lot of gaps and traps that you would need to fill and avoid for productive use. You have been warned!

ℹ Note: The commands and some of the tools are geared towards Mac as this is what I use. You should be able to follow the same steps on Windows using Cygwin as *NIX environment, but your milage may vary. This procedure is untested on Windows.

:!: Caveat: If you want to follow along with your own app make sure you have a backup of your current app and create a new branch in your git repository. You use version control, right? If not stop here and fix that first.

Goal #1: Keep your app runnable

In order to be able to identify if a problem arises due to the environment or changes we made to the app in the process we need to be able to switch back and forth between Ruby and JRuby as runtime. RVM the Ruby Version Manager allows us have multiple environments in parallel and have for example on terminal open to run the app on Ruby and another one for JRuby.

To get started we install RVM by executing the following in a terminal window. For more details and background information see https://rvm.io/

curl -L https://get.rvm.io | bash -s stable --ruby

This gives us the latest ruby version (1.9.3) as of this writing.

We can switch into the rvm environment with the following command:

rvm ruby-1.9.3

Note: It's a good practice to use gemsets to separate the dependencies of different apps in RVM. We won't go there as we focus on one app, but you should read https://rvm.io/gemsets/

In order to manage all the gems we need for the different environments we use bundler and the Gemfile.

As we now entered a new Ruby environment you don't have the gems available to you installed outside. So we need to install the gems first.

sudo gem install bundler
bundle

The second command installs all gems that are listed in your Gemfile. If you are on a older rails version you might need to create the Gemfile first and do some prep work for bundler. See here: http://gembundler.com/rails23.html

Now we should be all set and your app should start as normal with

rails server

Goal #2: Make it run on jRuby

Now that we have the app running on RVM we can migrate it to jRuby. As a first step we need to setup a jRuby RVM which is very straight forward and simple.

rvm install jruby

Once the installation is done we switch into the jruby RVM. It's best to do this is a new terminal window so you can keep the two environments up in parallel. Make sure you don't confuse the two terminal though.

rvm jruby

Next we need to install the gems again, but before we do that we make some changes that are required for jRuby on the Gemfile. As jRuby runs on Java we need to switch from native database access to JDBC. Also you need to check other native gems that you might be using and find a substitute that supports jRuby (e.g. exchanging the native javascript therubyracer gem with therubyrhino).

To keep the app working both on plain ruby and jruby we use the platforms feature of the Gemfile as outlined in the excerpt below. 

...
platforms :jruby do
  gem 'jruby-openssl'
  gem 'jruby-jars'
  gem 'jruby-openssl'
  gem 'jruby-rack'
  gem 'jdbc-maxdb', :git => 'https://github.com/SAP/cloud-jdbc-maxdb-gem.git'
  gem 'activerecord-maxdb-adapter', :git => 'https://github.com/SAP/activerecord-maxdb-adapter.git'
  gem 'activerecord-jdbc-adapter'
  group :development, :test do
    gem 'jdbc-sqlite3'
    gem 'warbler'
    gem 'activerecord-jdbcsqlite3-adapter'
  end
end
platforms :ruby do
  group :production do
    gem 'mysql'
  end
  group :development, :test do
    gem 'sqlite3'
  end
end
...

Now we can try to install the gems in the jRuby RVM

sudo gem install bundler
bundle

If there are errors because of other native gems that you missed move it into the platforms :ruby section and find a replacement that you then add to the platforms :jruby section of the Gemfile. Run bundle again and iterate until all errors are resolved.

Before we now start the app we need to adapt the database configuration in database.yml for the use of jdbc. Unfortunately I haven't found a good way to keep this environment independent. One option might be to create additional entries like development_jruby and set the RAILS_ENV accordingly. For now I just comment the changed lines so I can switch back and forth easily. Let me know if you have a better solution.

development:
#  adapter: sqlite3
  adapter: jdbcsqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000

That's it now you can start your application as usual with

rails server

Now that your app runs successfully on jruby RVM in development mode you can refer back to Krum's blog for the required changes in the production environment to run it on JPaaS. With RVM you can skip the jruby -S prefix on all commands he lists with it.

Have fun and let me know if I missed some thing as this was a side project run over several month so minor details might have slipped.

-- Michael