如何从Java传递Javascript本机类型到Nashorn对象?

时间:2015-09-26 12:58:41

标签: javascript java-8 nashorn

出于安全考虑,我希望传递给Nashorn本机Java类型的JS函数。

如果我创建引擎并运行以下命令:

        NashornScriptEngineFactory nashornScriptEngineFactory = new      NashornScriptEngineFactory();
        ScriptEngine engine = nashornScriptEngineFactory.getScriptEngine();
        engine.eval(script);
        Invocable invocable = (Invocable) engine;
        JSObject objectWork = (JSObject) engine.get("objectWork");
        objectWork.call(null,"eee");

脚本为

function objectWork(arg){
   print ("arg is "+ typeof arg);
   print ("arg.getClass()"+ arg.getClass());

   for (var k in arg){
        print(k);
   }
}

输出

arg is string
arg.getClass()class java.lang.String

我对第二个不太满意,而且我不知道getClass是否暴露了java.lang.Class对象的任何方法。有没有办法传递包含扩展Nashorn自己的JSObject的本地Java字符串的东西?

2 个答案:

答案 0 :(得分:1)

JS String基元类型值是java.lang.String对象。例如,

jjs> "hello".getClass()
class java.lang.String
jjs> "hello".class
class java.lang.String

即,在nashorn中没有使用单独的“JS String”类型。 Nashorn试图尽可能避免包装Java / JS类型。

您担心的具体问题是什么?通过“Class”对象反射访问String?请注意,默认情况下,如果在SecurityManager下运行,则不允许对脚本进行Java反射。

$ jjs -J-Djava.security.manager
jjs> "hello".class
class java.lang.String
jjs> "hello".class.getMethods()
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "nashorn.JavaReflection")
jjs>

因此,除非您将“nashorn.JavaReflection”RuntimePermission赋予脚本,否则它将无法从脚本执行任何Java反射。因此,访问任何Java对象的Class对象都不会构成任何安全线程。

答案 1 :(得分:0)

一个微不足道但又有效的解决方案。让引擎加载一段JS代码,如

JSObject strclone = (JSObject) engine.get("strclone");
JSObject jsString = strclone.call(null,"some Java string");
someOtherJsMethod.call(null, jsString);

然后每次从Java调用它。这将产生一个JSObject和一个可以传递给JS函数的属性JS字符串:

yield