Java调用代码:
import jdk.nashorn.api.scripting.*;
....
myCustomHashMap dataStore = new myCustomHashMap();
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("nashorn");
engine.put("dataStore",dataStore);
engine.eval(new java.io.FileReader("test.js"));
((Invocable)engine).invokeFunction("jsTestFunc", "testStr" );
使用Javascript:
function jsTestFunc (testParam)
{ dataStore.a = [1,2,3];
dataStore.b = {First:"John",Last:"Doe",age:37}; }
目标:
I need to JSONify the dataStore after the script execution
with no dependence on the script for assistance
dataStore.a -> jdk.nashorn.internal.objects.NativeArray
dataStore.b -> jdk.nashorn.internal.scripts.JO4
对于每个Map值,我尝试过以及:
我已尝试覆盖HashMap.put()
方法,但似乎不会在分配时转换为ScriptObjectMirror
,仅在显式函数调用上:
dataStore.x = [1,2,3] ; -> jdk.nashorn.internal.objects.NativeArray
javaHost.javaFunc( [1,2,3] ); -> ScriptObjectMirror
我真的需要使用myCustomHashMap(时间戳更改并维护更改列表等),所以我不能从根本上改变这种安排。我该怎么做才能恢复这些数据?
答案 0 :(得分:1)
这是一个错误。
使用jdk8u40以后,只要脚本对象传递给Java层,脚本对象就会转换为ScriptObjectMirror - 即使使用Object类型参数或分配给Object []元素。执行过程到脚本边界时,会自动解包这些包装的镜像实例。即,假设一个Java方法返回恰好是ScriptObjectMirror对象的Object类型值,那么脚本调用者将看到它是一个ScriptObject实例(镜像自动解包)
https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes
使用JDK8u40 Early Access Release
爪哇:
public class MyObject extends HashMap<String, Object> {
@Override
public Object put(String key, Object value) {
System.out.println("Key: " + key + " Value: " + value + " Class: " + value.getClass());
return super.put(key, value);
}
}
JavaScript的:
var MyObject = Java.type("my.app.MyObject");
var test = new MyObject;
test.object = {Test : "Object"};
test.array = [1,2,3];
控制台:
Key: object Value: [object Object] Class: class jdk.nashorn.api.scripting.ScriptObjectMirror
Key: array Value: [object Array] Class: class jdk.nashorn.api.scripting.ScriptObjectMirror