0

Java アプリケーションから JRuby を (JRuby 1.5 に含まれる JSR233 インターフェースを介して) 使用して、Java インターフェースの Ruby 実装をロードしようとしています。

私のサンプル実装は次のようになります。

インターフェース:

package some.package;
import java.util.List;
public interface ScriptDemoIf {
    int fibonacci(int d);
    List<String> filterLength(List<String> source, int maxlen);
}

Ruby の実装:

require 'java'
include Java

class ScriptDemo
  java_implements some.package.ScriptDemoIf
  java_signature 'int fibonacci(int d)'
  def fibonacci(d)
    d < 2 ? d : fibonacci(d-1) + fibonacci(d-2)
  end

  java_signature 'List<String> filterLength(List<String> source, int maxlen)'
  def filterLength(source, maxlen)
    source.find_all { |str| str.length <= maxlen }
  end
end

クラスローダー:

public ScriptDemoIf load(String filename) throws ScriptException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("jruby");
    FileReader script = new FileReader(filename);
    try {
        engine.eval(new FileReader(script));
    } catch (FileNotFoundException e) {
        throw new ScriptException("Failed to load " + filename);
    }
    return (ScriptDemoIf) m_engine.eval("ScriptDemo.new");
}

(明らかに、実際のローダーはもう少し汎用的です。実装クラス名が「ScriptDemo」であるとは想定していません。これは単純にするためです)。

問題 - ローダーの最後の行でクラス キャスト例外が発生します。これは、インターフェイスにうまくキャストされない型をengine.eval()返します。RubyObject私がウェブ上で読んだものからjava_implements、Ruby セクションの全体的な使用ポイントは、インターフェイスの実装を適切にコンパイルするためのものであるという印象を受けました。

私は何を間違っていますか?

4

1 に答える 1

2

そうあるべきですが、残念ながらまだそのように配線されていません。今のところ、Ruby クラスに基づいて Java ソース ファイルを作成するコマンドで#java_implementsのみ#java_signature使用されます。jrubyc --javaそれを Ruby 統合に使用することを検討することをお勧めします。

将来的には、この例がプリコンパイル済みスクリプトとランタイム実行スクリプトの両方で機能することを目指しています。このスクリプトを意図したとおりに動作させたい場合は、代わりに を使用してみてinclude Java::some.package.ScriptDemoIfくださいjava_implements

于 2011-01-06T17:23:27.720 に答える