5

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 值,我尝试过但失败了:

  • 转换为 ScriptObject 或 ScriptObjectMirror
  • 投射到地图或列表
  • 直接访问 JO4/NativeArray 方法
  • ScriptUtils.wrap() / ScriptUtils.unwrap()

我尝试过覆盖该HashMap.put()方法,但它似乎没有被转换为 a ScriptObjectMirroron assignments,仅在显式函数调用上:

dataStore.x = [1,2,3] ; -> jdk.nashorn.internal.objects.NativeArray

javaHost.javaFunc( [1,2,3] ); -> ScriptObjectMirror

我真的需要使用 myCustomHashMap (它时间戳更改并维护更改列表等),所以我不能从根本上改变这种安排。我该怎么做才能恢复这些数据?

4

1 回答 1

1

这是一个错误。

从 jdk8u40 开始,只要脚本对象被传递到 Java 层,脚本对象就会被转换为 ScriptObjectMirror——即使是使用 Object 类型参数或分配给 Object[] 元素。当执行跨越脚本边界时,这种包装的镜像实例会自动解包。即,假设一个 Java 方法返回的对象类型值恰好是 ScriptObjectMirror 对象,那么脚本调用者将看到它是一个 ScriptObject 实例(镜像会自动解包)

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes

JDK8u40 早期访问版本

爪哇:

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
于 2015-02-11T06:33:10.437 回答