Как получить от 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
,