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