[英]Calling Ruby method from Java
我有一個依賴於 ruby 腳本結果的 Java 應用程序。 我面臨的問題是這個 ruby 腳本被多次調用,每次執行時都需要加載腳本的庫。
我不熟悉 Ruby,但在我的搜索中我遇到了 JRuby。 由於它解釋 ruby 代碼並在 JVM 上運行它,我最初的想法是“太好了,我可以將 ruby 腳本編譯為 .class 文件並將其打包並像常規 java 對象一樣與之交互”。 這將避免每次執行 ruby 腳本時加載庫所帶來的開銷。
在深入研究 jruby 之后,我明白它不是這樣工作的。 所以為了做我想做的事,我可以使用 JRuby 的 JavaEmbedUtils
這就是我的想法(我很快就會測試)
// 1
List<String> paths = new ArrayList<>();
paths.add(".");
Ruby runtime = JavaEmbedUtils.initialize(paths);
// 2
String script = "/path/to/script.rb";
IRubyObject recvr = JavaEmbedUtils.newRuntimeAdapter().eval(runtime, script);
// 3 Call this many times
JavaEmbedUtils.invokeMethod(runtime, receiver, "method", null, null);
我的理解是否正確,因為這種方法允許我在加載腳本庫一次時多次使用腳本的內容? 有沒有替代的或更多的 JRuby 方式來做我正在尋找的事情?
更新
因此,我測試了類似於 Eugene 建議的內容 (a) 即 ScriptingContainer 並將其與使用 (b) java.lang.Runtime 調用腳本進行了比較,總共運行了 30 次。
這就是我在 Java 代碼的腳本容器中使用 JRuby 的方式:
import org.jruby.*;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.PathType;
import org.jruby.embed.ScriptingContainer;
ScriptingContainer container = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
container.setCompileMode(RubyInstanceConfig.CompileMode.OFF);
container.setNativeEnabled(false);
container.setObjectSpaceEnabled(true);
container.put("some_param", someValue);
// My script return an array - tweak to fit your returning value
RubyArray resourceArray = (RubyArray) container.runScriptlet(PathType.CLASSPATH, scriptPath);
我必須注意到 JRuby 在啟動時太慢(這些數字不太精確,但在我的情況下,即使在 4Ghz + SSD 上也是 2-3 秒)。 TDD 會因這種延遲而變得痛苦。 這就是為什么要對對象空間等進行一些調整的原因。
此外,我必須刪除這個模塊,以便其余的測試使用其他裝置並在不啟動 JRuby 的情況下運行。 換句話說,我不必在單獨運行另一個測試時啟動它。
聚苯乙烯
我的理解是否正確,因為這種方法要求我只加載一次腳本的依賴項?
我不確定你在這里是什么意思,但似乎每次使用這種方法時,JRuby 端“需要”的所有依賴項都會被加載。
無論如何,我之前會做一個基准測試。 也許不值得考慮。
更新:
這比我想象的要簡單:
常見的.rb:
puts "common"
腳本.rb:
require 'common'
puts "script"
代碼:
ScriptingContainer container = new ScriptingContainer(LocalVariableBehavior.PERSISTENT);
for (int i = 0; i < 3; i++) {
container.runScriptlet(PathType.CLASSPATH, "script.rb");
}
輸出:
common
script
script
script
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.