Jar of Rubygems

I find Rubygems a great tool for manging dependencies for an application; Yehuda Katz’ recent work on the bundler gem has made that even better, by allowing you to specify and transport dependency instructions with your application. For most Ruby applications Bundler works really well. It’s fast approaching 1.0 and will be a part of the immenent Rails 3.0 release.

However. The project I am currently working is leveraging Jruby. The main reason for choosing JRuby was that this applications main data source is a .Net soap service. My initial experiments led me to find that Ruby’s SOAP implementation and the various gems didn’t really want to play nice with .Net implementation that I was working with. Hmm, Java has lots of awesome SOAP libraries, maybe I could use JRuby and levergae them. AXIS to the rescue, and it’s all been going swimmingly since.

Problem arose however when I went to use Bundler in a Tomcat instance. Creating a war using warbler and deploying it to a Tomcat instance; and well of course Tomcat has no idea how to install and/or build gems.

Turns out I can create a mini-gems repoository and store it inside a JAR. Nick Sieger has a great post about it here, but I summarize and share my experience below:

$ java -jar jruby-complete-1.4.0.jar -S gem install -i ./gem_dependecies active_support maraku --no-rdoc --no-ri

$ jar cf gem_dependencies.jar -C gem_dependencies .

Now you’ve created a jar that is basically a mini-rubygem repository. If you require ‘gem_depedencies’ then require ‘rubygems’ all those gems in the gem_dependencies.jar will be available.

One small gotcha I encoutered though, if you(or `rackup` in my case) require ‘rubygems’ first, then the gems in gem_dependencies will not be added the Gem load_paths.

You need to Gem.clear_paths after requiring your dependency bundle to force Rubygems to set_paths again.


require 'rubygems'
require 'dependency_bundle.jar'

# Force Rubygems to reload the gem paths
Gem.clear_paths

After clearing up that little issue every works wonderfully.

Respond to this post