Friday, July 20, 2007

JRuby runtime initialization and problems with 'require'

I have been battling an issue with JRuby, where I got the following exception when trying to evaluate a ruby script from Java:

`require': no such file to load -- rubygems (LoadError)

I was not using the JSR-223 API (which is only part of Java6 and on), but simply programming directly against the JRuby apis. What I was doing was in the line of this:

public class MyApp {
static String jrubyHome = "C:\\software\\jruby\\jruby-0.9.8";
static {
System.setProperty("jruby.base", jrubyHome);
System.setProperty("jruby.home", jrubyHome);
System.setProperty("jruby.lib", jrubyHome + "\\lib");
System.setProperty("jruby.shell", "cmd.exe");
System.setProperty("jruby.script", "jruby.bat");
}

public static void main(String[] args) throws IOException {
Ruby runtime = Ruby.getDefaultInstance();
runtime.evalScript(...my script here...); // => failed in require of rubygems
}
}

After diving into the sources (I love open-source), I found out that load-path was initialized in LoadService.init and I then traced calls to this method. Seems like this method is called from:
  • The main method of the jruby command-line tool, which also adds some extra paths if given on command-line
  • The IRBApplet start() method
  • The IRBConsole main method
  • A lot of tests
  • From JavaEmbedUtils.initialize, which is what JSR-223 implementations are supposed to use in their implementations
Seems like an important method to remember to call :-)

The problem was fixed when I simply added the line:
        runtime.getLoadService().init(new ArrayList());

But of course, I should simply use JavaEmbedUtils to get my Ruby instance. Lesson learned!

No comments: