Enforce JRuby to use gems inside the JRuby complete and ignore the local gem repository

Most of us are aware that Gems can be bundled as part of JRuby Complete, and Jruby will automatically load these gems from the jruby-complete.jar happily.

But do you know that, if you had a local gem repository set, jruby will ALWAYS attempt load the gems ONLY from your local gem repository? And ignore the gems bundled inside the jruby-complete.jar?

Well, we are aware of that, but it was quite annoying when we find that some code that worked happily in our development environment does not work in production, bcos the codes were referring to some gems that were available only in our development environment.

To ensure JRuby completes ignores our local gem repository, we used to add the following line in our deployment scripts before launching JRuby.

unset GEM_HOME

We are trying to understand the principle behind using the local gem repository even though certain gems are bundled inside the Jruby Complete.

Some thoughts on how Jruby should choose the gem repository
1. Whenever jruby is launched from the jar file with embedded ruby home, then always assume to use the embedded gem home and ignore the local gem repository?

OR

2. If atleast one gem is bundled in jruby-complete, then can jruby assume the developer wants to use the particular gem in his application and hence ignore the local gem repo and set the gem repo as the embedded gems location inside jar?

We are unable to come to a conclusion on what is the sane approach to handle the situation.

For now, we have patched jruby to go thru first approach. This way, I am completely sure that when jruby is launched from jar, my local gem repository is not coming in the way. And I dont have to remember to “unset GEM_HOME” in all my deployment scripts to tell Jruby to look for gems embedded in the jar file.

Hope this may be of some help for people who have had faced this issue.

JOpenSSL gem inside JRuby Complete

We had faced quite a lot of issues trying to embed JOpenSSL inside jruby-complete.jar.

We used to get an error “Uninitialized constant OpenSSL::Digest::OPENSSL_VERSION_NUMBER” with the following stack trace :

NameError: uninitialized constant OpenSSL::Digest::OPENSSL_VERSION_NUMBER
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/jruby-openssl-0.6/lib/openssl/cipher.rb:28:in `const_missing’
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/jruby-openssl-0.6/lib/openssl/digest.rb:23
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/jruby-openssl-0.6/lib/openssl/digest.rb:31:in `require’
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/jruby-openssl-0.6/lib/openssl.rb:24
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/jruby-openssl-0.6/lib/openssl.rb:31:in `require’
from file:/home/msuser1/jruby-complete-1.3.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’

You can find Charles’ explanation here

What we did is the following :

1. Add the Jruby-openssl gem inside the jruby-complete.jar bundle like adding any other gems(rspec, rake etc.)
2. Extract the JRuby Complete Jar in a fresh folder
3. In addition to this, extract the contents of jopenssl.jar directly under the root folder. (jopenssl.jar is located inside the lib folder of the jruby-openssl gem).
4. Re-create the jruby-complete.jar from this exploded folder.

Thats about it, you are all set to use openssl inside jruby without any issue.

Please note, at the time of writing this post, I was using JRuby 1.3.1 and Jopenssl 0.6.