我想从Java应用程序中使用JRuby(通过JRuby 1.5中包含的JSR233接口)加载Java接口的ruby实现。如何从JRuby获得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
类型,这种类型不能很好地转换到我的界面。从我在网上阅读的东西中,我得到的印象是Ruby部分中使用的全部使用点java_implements
是为了适当地编译接口实现。
我在做什么错?
谢谢!那确实解决了这个问题。我的替代方法是让加载器执行'Object l = m_engine.eval(simpleName +“.new”);不可调用i =(可调用)m_engine;返回i.getInterface(l,ScriptDemoIf.class);`这很丑陋... – Guss 2011-01-06 18:38:18