1

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()});
    }
}
4

1 に答える 1

1

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");
于 2013-01-15T17:24:20.913 に答える