Search code examples
javarubygemsjruby

JRuby+Java: How to find my locally installed Gems in my jar


(Crossposting note: This question was also posted at the JRuby forum two weeks ago, but hasn't been answered)

I'm on Windows, with JRuby 1.7.23 (but I think this doesn't matter for this question).

My project directory has the following subdirectories:

  • javas (contains the Java source files)
  • rubies (contains the Ruby source files)
  • gem (contains my gems)

That is, I am using a local gem directory, not the default location.

I install my gems with

jruby -S gem install GEMNAME --install-dir ./gem

and set the environment variable GEM_HOME to my ./gem directory

If I had a pure JRuby application, it would find my installed gems (I tried this). The problem is that I have a mixed Java+JRuby application, which is supposed to be run from a jar file. I'm creating my jar file like this:

jar cvfm app.jar manifest.mf -C . Main.class javas\*.class rubies gem

which, as I can see, nicely packs my gems into the jar file. When I run my application with

java -cp c:\jruby\jruby.jar;app.jar Main

I get an exception when I require one of my installed gems, saying that the Gem is not found - which is not surprising, because GEM_HOME doesn't have any meaning when the application is run from the jar file, isn't it?

I need a different way to tell my application, where the Gems are found. What is the best approach in this case? Should I explicitly manipulate the $LOAD_PATH, and if yes, how? Or can I set GEM_HOME somehow so that it points to the Gem directory inside the jar?

UPDATE: I think I found a way to solve the problem, but it looks a bit cumbersome, and I wonder, if there isn't a better approach. Anyway, here is the solution I came up with:

I know that all gems needed are in my jar file, and below the relative directory 'gem'. I also know that the Ruby sources are in a directory called lib, somewhere down the path (for example, gem/gems/GEMNAME/lib/GEMNAME.rb). Hence I traverse the directory tree starting with the top directory (gem), and add all pathes to lib directories (gem/gems/GEMNAME/lib) to $LIB_PATH, before I do any require.

Can this be done any better?


Solution

  • OK, I found what's going wrong (thanks to a hint I got on JRuby forum to a different topic), and how to easily solve it:

    First, when generating a jar file for delivering my application, I must not include jruby.jar which comes with the JRuby installation, but have to use jruby-complete.jar of the appropriate JRuby version, which can be downloaded separately from the JRuby Download page - in my case, this is jruby-complete-1.7.23.jar.

    Next, I must include my gem directory not with

    jar cvfm .... gem
    

    but with

    jar cvfm .... -C gem .
    

    (i.e. "-C", gem-directory, period). This is nicely explained in Nick Sieger's article gem-in-a-jar.

    That's all!