Как получить от JRuby правильно типизированную реализацию Ruby интерфейса Java?

Я пытаюсь использовать 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 ответ

Решение

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

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

Другие вопросы по тегам