Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a public & concrete instance of Nashorn's ScriptObjectMirror available in Java?

Tags:

java

nashorn

I'm basically wanting to go:

ScriptObjectMirror myObj = new ConcreteScriptObjectMirror();

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

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

I'm doing that now, but Nashorn is complaining:

TypeError: Cannot apply "with" to non script object

So the Java object I pass in needs to be an instance of ScriptObjectMirror.

like image 208
Kong Avatar asked Jul 11 '14 06:07

Kong


1 Answers

I had the same problem and just in case you haven't found your answer yet. I think the following snippet of code may contain what you want. I'm using javax.script.SimpleBindings to pass the object to the 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, Nashorn documentation is pretty bad right now, so I hope that may be helpful.

like image 195
megothss Avatar answered Sep 19 '22 10:09

megothss