使用rvm jruby install将JRuby嵌入Java代码中

我正在尝试从Java应用程序中嵌入和评估ruby代码。 我没有将jruby-complete.jar放在我的类路径中,而是需要能够使用与rvm一起安装的jruby环境。 我可以执行基本的内核代码,但是我遇到了需要标准库(fileutils,tmpdir等)的问题。

我在下面创建了一个使用通过RVM安装的JRuby的测试文件,如果你有一个本地的rvm + jruby安装(将JRUBY_VERSION更改为安装的版本),任何人都应该能够编译+运行它。 我意识到我引用的jruby.jar与jruby-complete.jar不同,但我希望有一种方法可以在不下载外部jar的情况下加载标准库。

import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.logging.Logger; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Test { private final static Logger LOG = Logger.getAnonymousLogger(); private final static String JRUBY_VERSION = "jruby-1.6.7"; public static void main(String[] args) throws Throwable { final String rvmPath = System.getenv("HOME") + "/.rvm/rubies/"; addFileToClasspath(rvmPath + JRUBY_VERSION + "/lib/jruby.jar"); final ScriptEngine rubyEngine = new ScriptEngineManager().getEngineByName("jruby"); rubyEval(rubyEngine, "puts 'hello world!'"); // works rubyEval(rubyEngine, "require 'tempfile'"); // fails to load 'tmpdir' rubyEval(rubyEngine, "require 'fileutils'"); // fails to load 'fileutils' } private static void rubyEval(ScriptEngine rubyEngine, final String code) { try { rubyEngine.eval(code); } catch (final Throwable e) { LOG.throwing(Test.class.getName(), "rubyEval", e); }; } public static void addFileToClasspath(final String path) throws Throwable { final File file = new File(path); final URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); final Class sysclass = URLClassLoader.class; final Method method = sysclass.getDeclaredMethod("addURL", new Class[] {URL.class}); method.setAccessible(true); method.invoke(sysloader, new Object[] {file.toURI().toURL()}); } } 

在rvm安装上,核心ruby文件与jruby.jar一起安装(此处为JRuby 1.7.2):

 sebastien@greystones:~$ cd .rvm/rubies/jruby-1.7.2/ sebastien@greystones:~/.rvm/rubies/jruby-1.7.2$ find . -name fileutils.rb ./lib/ruby/1.8/fileutils.rb ./lib/ruby/1.9/fileutils.rb sebastien@greystones:~/.rvm/rubies/jruby-1.7.2$ find . -name tmpdir.rb ./lib/ruby/1.8/tmpdir.rb ./lib/ruby/1.9/tmpdir.rb 

因此,您需要将正确的ruby文件夹(取决于ruby版本)添加到类路径中,例如:

  final String rvmPath = System.getenv("HOME") + "/.rvm/rubies/"; addFileToClasspath(rvmPath + JRUBY_VERSION + "/lib/jruby.jar"); // Here, add folder to classpath. System.setProperty("org.jruby.embed.class.path", rvmPath + JRUBY_VERSION + "/lib/ruby/1.9");