Reading Nashorn JO4 and NativeArray

时光总嘲笑我的痴心妄想 提交于 2019-12-10 14:57:43

问题


Java calling code:

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}; }

Goal:

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

For each Map value, I've tried and failed with:

  • Casting to ScriptObject or ScriptObjectMirror
  • Casting to Map or List
  • Accessing JO4/NativeArray methods directly
  • ScriptUtils.wrap() / ScriptUtils.unwrap()

I've tried overriding the HashMap.put() method, but it appears not to be converted to a ScriptObjectMirror on assignments, only on explicit function calls:

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

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

I really need to use myCustomHashMap (it timestamps changes and maintains a change list, etc), so I can't radically alter this arrangement. What can I do to get this data back out?


回答1:


This is a bug.

With jdk8u40 onwards, script objects are converted to ScriptObjectMirror whenever script objects are passed to Java layer - even with Object type params or assigned to a Object[] element. Such wrapped mirror instances are automatically unwrapped when execution crosses to script boundary. i.e., say a Java method returns Object type value which happens to be ScriptObjectMirror object, then script caller will see it a ScriptObject instance (mirror gets unwrapped automatically)

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

With JDK8u40 Early Access Release

Java:

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];

Console:

Key: object Value: [object Object] Class: class jdk.nashorn.api.scripting.ScriptObjectMirror
Key: array Value: [object Array] Class: class jdk.nashorn.api.scripting.ScriptObjectMirror


来源:https://stackoverflow.com/questions/26392602/reading-nashorn-jo4-and-nativearray

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!