2015-09-26 92 views
1

出於安全原因,我想傳遞給Nashorn本機Java類型的JS函數。如何將Javascript本機類型從Java傳遞給Nashorn對象?

如果我創建一個引擎,我運行以下命令:

 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 String的東西傳遞給一個本地的擴展Nashorn自己的JSObject?

+0

可以擴展'JSObject',但我不確定這是個好主意。該類位於['jdk。*'](https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/JSObject.html)包中。 – Tunaki

+0

我見過它,但我沒有看到任何明顯的方式使它成爲一個js字符串,只是一個具有屬性的常規對象。此外,它沒有任何是基本類型的方法,如數字字符串等... – gotch4

回答

0

一個微不足道的工作解決方案。只需讓引擎加載一塊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); 
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類型。

您擔心的具體問題是什麼?通過「類」對象反射訪問字符串?請注意,默認情況下,如果您在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對象都不會構成任何安全線程。

相關問題