Is there a public and specific instance of Nashorn ScriptObjectMirror available in Java?

Basically I want to go:

ScriptObjectMirror myObj = new ConcreteScriptObjectMirror(); 

And then call some JS like this, where myObj is the parameter:

 function myJSFunc(param) { with(param) { return paramProperty; } } 

I am doing it now, but Nashorn complains:

TypeError: cannot apply β€œc” to script object

So, the Java object I am passing must be an instance of ScriptObjectMirror.

+6
source share
3 answers

I had the same problem, and just in case, you have not yet found the answer. I think the following code snippet may contain what you want. I use javax.script.SimpleBindings to pass an object to a JavaScript function.

 import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleBindings; public class Demo { public static void main(String[] args) throws Exception { Demo demo = new Demo(); String result = demo.execute(); System.out.println("full name is " + result); } public String execute() throws ScriptException, NoSuchMethodException { final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); final Compilable compilable = (Compilable) engine; final Invocable invocable = (Invocable) engine; final String statement = "function fetch(values) { return values['first_name'] + ' ' + values['last_name']; };"; final CompiledScript compiled = compilable.compile(statement); compiled.eval(); SimpleBindings test = new SimpleBindings(); test.put("first_name", "John"); test.put("last_name", "Doe"); FullName fullName = invocable.getInterface(FullName.class); return fullName.fetch(test); } public interface FullName { String fetch(SimpleBindings values); } } 

IMHO, the documentation in Nashorn is very bad, so I hope this can be useful.

+3
source

Since ScriptObjectMirror is final, you cannot propagate from this class. ScriptObjectMirror is used by the Nashorn engine to pass JavaScript objects on the Java side, and not vice versa.

When calling javascript functions from java code, you can simply pass an arbitrary java object to a function:

 ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval(new FileReader("myScript.js")); Invocable invocable = (Invocable) engine; Object result = invocable.invokeFunction("myJSFunc", "Peter Parker"); System.out.println(result); 

See this article for more examples: http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/

0
source

I don’t have time to check it right now, but at the point where you pass myObj to the Nashorn engine, try using Java.from (foo).

So in your example you can do:

 function myJSFunc(param) { with(Java.from(param)) { return paramProperty; } } 

Perhaps you are passing a Java object (ScriptObjectMirror) when this is the wrapper for your JavaScript object, calling Java.from () will open this for you.

some explanation here: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions (search java.from)

0
source

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


All Articles