I have created a gem on my local system for text mining which relies on external Java libraries for classification tasks. I'm trying to harness the power of Java through JRuby here. Directory structure is as follows:
- classifier/
* classifier.gemspec
* Gemfile
* Gemfile.lock
* lib/
* classifier/
* version.rb
* sample_classifier.rb
* classifier.rb
* java/
* sample_lib.jar
* another_sample_lib.jar
* yet_another_sample_lib.jar
* Rakefile
I'm loading these jars in lib/classifier.rb
as
Dir["java/*.jar"].each{|jar| require jar}
I have added this gem to a Git repository and referenced it in the
Gemfile of my Rails 3.0.9 project. However, my sample_classifier.rb
fails to locate any classes 'import'ed from any of the jars under
lib/java
.
Things work if I copy lib/java
to my Rails application
lib/ directory
and add the following in sample_classifier.rb
:
Dir["lib/java/*.jar"].each{|jar| require jar}
However, I don't think it's a good practice to spill the gem's dependencies in my Rails app. Is there a better way to achieve this? I looked around for bundling jar files with a gem but I found results for exactly the opposite i.e. bundling gems within a jar file. Can I add these jars to Rails' config.autoload_path or similar to load them when the application starts? Is it a good practice to bundle jar dependencies with the gem?
I'm sure there's a cleaner way to do this.
Might I suggest that managing your Jars with LockJar would be easier. Just install the gem
Create a Jarfile
Create a Jarfile that contains a list of your Jar dependencies:
The simplest jar notation is groupId:artifactId:version. Other supported variations are groupId:artifactId:type:version and groupId:artifactId:type:classifier:version.
Generating a Jarfile.lock
The transitive dependencies are resolved, download, and generate to a Jarfile.lock with the command line:
(You can also run it from Ruby as LockJar.lock)
Accessing your Jars
The Jarfile.lock contains all the Jar dependency information. Now you can load your jars from the Jarfile.lock to the classpath with:
When packaging with a Gem, you will need to ensure the Jars from Jarfile.lock have been downloaded with:
Make sure you request the Jarfile.lock is relative to the Gem's installed dir. Here is an example helper:
You can also setup your Gem to download the Jar dependencies when the Gem installs, removing the need to call
LockJar.install
.Use absolute paths like so: