Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java ScriptEngine: using value on Java side?

In a Java program I'm invoking a user-defined JavaScript program:

File userJSFile=...;
javax.script.ScriptEngineManager mgr=new  ScriptEngineManager();
javax.script.ScriptEngine scripEngine= mgr.getEngineByExtension("js");
Object result=scripEngine.eval(new java.io.FileReader(userJSFile));

Now I would like to use 'result': how can I have an access to it? Can I identify it as an array (Can I iterate threw its members), a String, an Integer, etc... ?

Thanks

EDITED: I just know that my user gave me a script returning the last value. I don't know anything about this value. Is it a String, an array, etc.. ? I don't known but I want to use it.

like image 462
Pierre Avatar asked Jul 03 '09 08:07

Pierre


1 Answers

Except perhaps for simple values, I would rather let the scripting engine coerce its values to Java types.

public class ScriptDemo {

  static class Result {
    private String[] words;

    public void setWords(String[] words) {
      this.words = words;
    }
  }

  static final String SCRIPT = "var foo = 'Hello World!';\n"
      + "result.setWords(foo.split(' '));";

  public static void main(String[] args)
      throws ScriptException {
    Result result = new Result();
    javax.script.ScriptEngineManager mgr = new ScriptEngineManager();
    javax.script.ScriptEngine scripEngine = mgr
        .getEngineByExtension("js");
    scripEngine.getContext().setAttribute("result", result,
        ScriptContext.ENGINE_SCOPE);
    scripEngine.eval(SCRIPT);
    System.out.println(Arrays.toString(result.words));
  }

}

Even if you can't edit the script, you could take the return value and pass it through your own generated script to do the coercion. This assumes you know something about the value being returned.


EDIT: since nothing is known about the return value, I would first test it using Java (getClass()) to see if it was one of the java.lang types. If the returned object is from some API private to the library, I would introspect it using the scripting language (in this case JavaScript), possibly coercing it to a Java type or pushing its properties into some Java data structure during the process.

My JavaScript is rusty, but John Leach's tutorial looks quite good: JavaScript Introspection.

(You may be able to use Java reflection, but since the engine implementation could vary between Java versions/JREs/JavaScript engines, I wouldn't rely on it.)

like image 50
McDowell Avatar answered Oct 20 '22 00:10

McDowell