如何将Javascript原生类型从Java传递给Nashorn对象

How to pass Javascript native types to Nashorn objects from Java?

本文关键字:Nashorn 对象 Java Javascript 原生 类型      更新时间:2023-09-26

出于安全原因,我希望将javascript函数传递给Nashorn原生Java类型。

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

        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对象的任何方法。是否有一种方法可以传递一些东西,将Java字符串包装在本机扩展Nashorn自己的JSObject中?

JS字符串原语类型值是java.lang.String对象。例如,

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

。,在nashorn中没有使用单独的"JS字符串"类型。Nashorn尽量避免包装Java/JS类型。

你担心的具体问题是什么?通过"类"对象反射访问字符串?请注意,默认情况下,如果在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对象都不会产生任何安全线程。

一个简单但有效的解决方案。只需让引擎加载一段JS代码,如

function strclone(str){
 return new String(str);
}

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

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