Rhino将Java类传递给Javascript函数

时间:2014-08-14 21:38:49

标签: javascript exception scripting rhino

我在我的Java应用程序中嵌入Rhino并尝试从我的Java代码中获取JavaAdapter。 如果我这样做,它可以正常工作

(function() {
  return new JavaAdapter(packageName.InterfaceName, {
    methodA: function() {},
    methodB: function() {}
  });
})();

但是当我创建这个功能时

var getJavaAdapter = function(type, obj) {
  return new JavaAdapter(type, obj);
};

像我这样修改我的test.js文件

(function() {
  return {
    methodA: function() {},
    methodB: function() {}
  };
})();

并从我的Java代码中调用

private static Object invokeFunction(String functionName, Object... args) {
  Object obj = scope.get(functionName, scope);
  if (obj instanceof Function) {
    Function function = (Function) obj;
    Object result = function.call(context, scope, scope, args);
    return result;
  }
  return null;
}

private static <T> T getImplementation(Class<T> type, Object obj) {
  Object implementation = invokeFunction("getJavaAdapter", type, obj);
  return (T) JavaAdapter.convertResult(implementation, type);
}

...
Object obj = evalResource("/test.js");
getImplementation(InterfaceName.class, obj);

我得到了一些奇怪的例外

Exception in thread "main" org.mozilla.javascript.EcmaError: TypeError: Argument 0 is not Java class: interface packageName.InterfaceName. (/common.js#2)

我试过type.class,
我试过typeOf(type),
我尝试只传递类名,然后传递java.lang.Class.forName(className)
但仍然得到一些类似的异常“参数0不是Java类”

那我怎么能通过我的班级?

1 个答案:

答案 0 :(得分:2)

我不确定 JavaAdapter JavaScript类型是否真的需要 java.lang.Class 类型的对象,尽管错误消息会另有说明。

Context cx = Context.enter();
try {
  Scriptable scope = cx.initStandardObjects();
  String script = "java.lang.Runnable";
  Object result = cx.evaluateString(scope, script, "<cmd>", 1, null);
  System.out.println(result.getClass());
} finally {
  Context.exit();
}

以上代码打印 class org.mozilla.javascript.NativeJavaClass

这有效:

Context cx = Context.enter();
try {
  Scriptable scope = cx.initStandardObjects();
  NativeJavaClass rType = new NativeJavaClass(scope, Runnable.class);
  scope.put("rType", scope, rType);
  String script = "new JavaAdapter(rType," +
        "{ run : function() { java.lang.System.out.println('hi'); }" +
        "});";
  Object r = cx.evaluateString(scope, script, "<cmd>", 1, null);
  Runnable runnable = (Runnable) JavaAdapter.convertResult(r, Runnable.class);
  runnable.run();
} finally {
  Context.exit();
}

测试的版本是Rhino 1.7R4。