8

I have the following program, which executes Javascript in Java (nashorn) . The Javascript code is returning an object.

public Object execute(){
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine e = sem.getEngineByName("nashorn");  
        Invocable invocable = (Invocable)e;
        ScriptEngineFactory f = e.getFactory();
        Object result;
        try {
            String statement = "function fetch(value, count) { count++ ; return {'value': value,'count' : count} }; } ; ";
            CompiledScript cs = ((Compilable)e).compile(statement);
            cs.eval();
            result = invocable.invokeFunction("fetch", 10,2);

        }   
        catch (Exception se ) {
            String version = System.getProperty("java.version");
            System.out.println(version);
            result = "script exception ";
        }

How do I access the object values in my result object in Java? Initially, I tried using result.toString() to get results. Seems to return [Object Object]

Is there a way, where I could return the results to result object such that I could get values equivalent to result.value , and result.count (similar to Javascript) .

2 Answers 2

7

If the return value of your program is a JavaScript object, you should be able to cast it to jdk.nashorn.api.scripting.JSObject in Java and then use its methods (e.g. getMember()) to query and manipulate it.

Sign up to request clarification or add additional context in comments.

Comments

4

You don't return a JSObject from the JavaScript function. Valid would be

{
  value: value,
  count : count
}

So you could use this Java code.

package de.lhorn.so;

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 jdk.nashorn.api.scripting.JSObject;

public class SOPlayground {

    public static void main(String[] args) throws Exception {
        SOPlayground sop = new SOPlayground();
        JSObject jso = sop.execute();
        System.out.println("value=" + jso.getMember("value"));
        System.out.println("count=" + jso.getMember("count"));
    }

    public JSObject 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(value, count) { count++ ; return {value: value, count : count} };";
        final CompiledScript compiled = compilable.compile(statement);

        compiled.eval();

        return (JSObject) invocable.invokeFunction("fetch", 10, 2);
    }
}

Output:

value=10
count=3.0

3 Comments

Thanks a lot! JSObject saved my day. I was using ScriptObjectMirror which is a total no no in my case.
@Rahul The Nahorn JSObject interface is implemented by the jdk.nashorn.api.scripting.ScriptObjectMirror actually returned by invokeFunction.
I am currently using a cast to Map<String, Object>, which works fine because ScriptObjectMirror actually implements that interface... Should I use JSObject instead? I haven't found clear documentation on this yet... The Invocable interface just defines Object as return type, which is pretty useless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.