Java Scripting With Nashorn (JSR 223) & Pre-compilation

Kong picture Kong · Mar 31, 2014 · Viewed 7.6k times · Source

I am using Nashorn via JSR 223 to execute small snippets of user entered script:

public Invocable buildInvocable(String script) throws ScriptException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName(ENGINE);
    engine.eval(functions);
    engine.eval(script);
    return (Invocable) engine;
}

The varying user script calls JavaScript functions that are defined in a static, central library (held in the functions String in the code snippet above).

Every time I want to get hold of an Invocable that I can call from my Java I am constantly having to recompile the large library code.

Is there any way to join a previously compiled piece of code in with new code?

Answer

auntyellow picture auntyellow · Nov 27, 2014

Put compiled functions into Bindings like:

private static final String FUNCTIONS =
    "function() {" +
    "  return \"Hello\";" +
    "}";

public static void main(String... args) throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType("text/javascript");

    // Compile common functions once
    CompiledScript compiled = ((Compilable) engine).compile(FUNCTIONS);
    Object sayHello = compiled.eval();

    // Load users' script each time
    SimpleBindings global = new SimpleBindings();
    global.put("sayHello", sayHello);
    String script = "sayHello()";
    System.out.println(engine.eval(script, global));
}