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

标签 java rvm jruby jsr223

我正在尝试从 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");

关于java - 使用 rvm jruby install 将 JRuby 嵌入到 Java 代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14095744/

相关文章:

ruby - rspec tests under jruby on Windows running very slow

ruby-on-rails - Lion、RVM、Postgresql 和 PG Gem

ruby-on-rails - 打开新的终端窗口后,为什么需要使用 “rvm use default”?

ruby - 使用 RVM 安装 Ruby 版本时的配置问题

ruby - 如何使用puppet在服务器上设置环境变量?

ruby - 在 lambda 中存储方法并发送到对象

java - ListView 中的字符串样式,Android Dev

java - 为什么我可以实例化这个抽象类?

Java:多维数组

java - 检测SessionUnsubscribeEvent的目标 channel