Reading Nashorn JO4 and NativeArray

Java call 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 tried and failed with:

  • Cast to ScriptObject or ScriptObjectMirror
  • Listing for a card or list
  • Direct access to JO4 / NativeArray methods.
  • ScriptUtils.wrap () / ScriptUtils.unwrap ()

I tried to override the HashMap.put() method, but it does not translate to ScriptObjectMirror when assigned only to 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 (these are temporary changes and maintains a list of changes, etc.), so I cannot radically change this scheme. What can I do to return this data?

+5
source share
1 answer

This is mistake.

From jdk8u40 onwards, script objects are converted to ScriptObjectMirror whenever script objects are passed to the Java level - even with parameters of type Object or assigned to the Object [] element. Such wrapped mirror instances are automatically unpacked when execution crosses the border of the script. that is, say, the Java method returns a value of the type of the object, which is a ScriptObjectMirror object, then the calling script object will see an instance of ScriptObject (the mirror is automatically unpacked)

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

With early release JDK8u40

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 
+1
source

Source: https://habr.com/ru/post/1204774/


All Articles