Upgrade Rails 3.2 to Rails 4 on jRuby
Rails 4 is nearly ready, so I decided to upgrade a jRuby/Oracle project I’ve been working on to see how it fares on the new codebase.
I updated my Gemfile to point to head on the master branches of the relevant libraries… rails, journey, arel, coffee-rails, sprockets-rails (which is now in it’s own gem) and sass-rails. I added turbolinks and ran
This threw up some errors that suggested I run
bundle update, so I did.
Update project structure
A new rails 4 app adds a few things that aren’t present in Rails 3.x and earlier. One of which is that the
script has been replaced with a
bin folder. Run
rake rails:update to get the latest.
At this point, things blew up, and it’s a jRuby specific issue. When the rake task tried to boot the app it raised a NameError relating to the definition of MyApp::Application::Railties. This SO post has the details. In short, I took the monkey patching approach and added this to
Rails::Engine.class_eval do def railties @railties ||= self.class.const_get(:Railties).new end end
At this point, running
bin/rails console was raising an exception related to a
require active_resource/railtie line in
Rails 4 moved ActiveResource out into a separate gem, so if you need it you now need to include it in your Gemfile. I don’t use it, so I just removed the line.
This step is unnecessary if you are using
require 'rails/all' here, which is the default.
I was using
strong_parameters in the 3.2 version of the app but this is now baked into Rails 4, so I needed to remove
strong_parameters from my Gemfile.
jRuby and encrypted cookie store
At this point I was able to run the server and so fired it up. The first page request raised an error
uninitialized constant OpenSSL::PKCS5. Again, it’s a jRuby specific error, some discussion on it is here.
You are now using the new encrypted cookie store as default with Rails 4 and it isn’t playing nice with jRuby at the moment.
In short, you need to get onto the head version of jruby and if you have
jruby-openssl in your Gemfile, remove it.
Finally, there was one final problem that needed fixing. In the encrypted cookie store code, there is a class that is referenced but not previously defined. This raises an exception in jRuby so we need to ensure the class is defined. Get your monkey patching hat on again, in
class ActiveSupport::MessageVerifier::InvalidMessage < StandardError; end
That’s enough to get Rails 4 working on jRuby.