Как получить от JRuby правильно типизированную реализацию Ruby интерфейса Java? - PullRequest
0 голосов
/ 06 января 2011

Я пытаюсь использовать JRuby (через интерфейс JSR233, включенный в JRuby 1.5) из приложения Java для загрузки реализации ruby ​​интерфейса Java.

Мой пример реализации выглядит следующим образом:

Интерфейс:

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 заключается в правильной компиляции реализаций интерфейса.

Что я делаю не так?

1 Ответ

2 голосов
/ 06 января 2011

Так и должно быть, но, к сожалению, пока не совсем так. На данный момент #java_implements и #java_signature используются только командой jrubyc --java, которая создает исходный файл Java на основе класса Ruby. Возможно, вы захотите использовать это для интеграции с Ruby.

Мы стремимся к тому, чтобы этот пример в будущем работал как с предварительно скомпилированными сценариями, так и с исполняемыми сценариями. Если вместо этого вы хотите, чтобы этот скрипт работал должным образом, попробуйте использовать include Java::some.package.ScriptDemoIf вместо java_implements.

...