2011-01-06 22 views
0

我想從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是爲了適當地編譯接口實現。

我在做什麼錯?

回答

2

它應該是,但不幸的是,這種方式尚未完全接通。目前,#java_implements#java_signature僅用於創建基於Ruby類的Java源文件的jrubyc --java命令。您可能要考慮將其用於Ruby集成。

我們正在尋找這個例子來爲未來的預編譯腳本和運行時執行的腳本工作。如果您希望此腳本按預期工作,請嘗試使用include Java::some.package.ScriptDemoIf而不是java_implements

+0

謝謝!那確實解決了這個問題。我的替代方法是讓加載器執行'Object l = m_engine.eval(simpleName +「.new」);不可調用i =(可調用)m_engine;返回i.getInterface(l,ScriptDemoIf.class);`這很醜陋... – Guss 2011-01-06 18:38:18

相關問題