我想從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