Rhino 是 Mozilla 純 Java 實現的 JavaScript 引擎,常用於規則引擎、腳本化配置、動態業務邏輯。本文示範 Java 調用 JS 函數、JS 調用 Java 方法的完整流程。
<dependency>
<groupId>org.mozilla</groupId>
<artifactId>rhino</artifactId>
<version>1.7.14</version>
</dependency>
import org.mozilla.javascript.*;
public class RhinoExecutor {
public static Object execute(String jsCode, String functionName, Object[] args) {
Context cx = Context.enter();
cx.setOptimizationLevel(-1); // 解釋模式,避免類加載問題
try {
Scriptable scope = cx.initStandardObjects();
// 暴露 Java 物件給 JS
ScriptableObject.putProperty(scope, "javaHelper", Context.javaToJS(new JavaHelper(), scope));
cx.evaluateString(scope, jsCode, "script", 1, null);
Function func = (Function) scope.get(functionName, scope);
if (func == null) throw new RuntimeException("Function not found: " + functionName);
return func.call(cx, scope, scope, args);
} finally {
Context.exit();
}
}
// 供 JS 調用的 Java 類
public static class JavaHelper {
public String sayHello(String name) {
return "Hello from Java, " + name;
}
public int add(int a, int b) {
return a + b;
}
}
}
String jsCode = "function greet(name) { return 'JS says: ' + name; }";
Object result = RhinoExecutor.execute(jsCode, "greet", new Object[]{"World"});
System.out.println(result); // JS says: World
String jsCode =
"var helper = javaHelper;" +
"function callJava() {" +
" return helper.sayHello('Rhino');" +
"}";
Object result = RhinoExecutor.execute(jsCode, "callJava", new Object[]{});
System.out.println(result); // Hello from Java, Rhino
Android 預設不包含 Rhino,需額外引入 rhino-android 或使用內建 WebView.evaluateJavascript / JavascriptInterface。若必須用 Rhino,請確保:
rhino-1.7.14.jar 並啟用 MultiDex。Context.enter() 導致的執行緒安全問題,改用 ContextFactory。<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>22.3.0</version>
</dependency>
// 用法類似,效能更優、支援 ES2023
Context ctx = Context.create();
Value jsFunc = ctx.eval("js", "function add(a,b){return a+b;}");
int sum = jsFunc.execute(1, 2).asInt();
java.lang.System、java.io.File 等敏感類訪問。Context 與 Scriptable 減少初始化開銷。CompiledScript(JSR-223)。