user2749903
user2749903

Reputation: 1305

Nashorn put compiledsript into engine scope

I have two js files,

In my project im trying to precompile all javascripts during my application startup, and then at runtime only invoke CompiledScripts with desired parameters.

I ended up with the following code



    static String LIBRARY = "function hello(arg) {return 'Hello ' + arg;};";

    static String SCRIPT = "hello(arg)";

    public static void main(String... args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
        Compilable compilable = ((Compilable) engine);
        CompiledScript compiledLib = compilable.compile(LIBRARY);
        compiledLib.eval();

        CompiledScript actualScript = compilable.compile(SCRIPT);

        Bindings helloParams = new SimpleBindings();
        helloParams.put("arg","world");
        ScriptObjectMirror result = (ScriptObjectMirror) actualScript.eval(helloParams);
        System.out.println(result);
}

But this code throws an error

> compiledScript.eval(helloParams);
<eval>:1 ReferenceError: "hello" is not defined

How can i access context of "compiledLib" (ie methods and variables) from within the "actualScript"?

Upvotes: 0

Views: 393

Answers (1)

Andreas
Andreas

Reputation: 159086

Compiling doesn't register the hello() function, it just parses the JavaScript code.

You need to execute the code for the function to be registered.

Remember, in JavaScript, there is very little difference between these two statements, except that function declarations are hoisted and can therefore be used before the declaration statement:

function hello(arg) {return 'Hello ' + arg;};

var hello = function(arg) {return 'Hello ' + arg;};

There is therefore little reason to separately compile the LIBRARY code, you just run it and save off all the created global variables, which are the library methods. E.g. after executing your LIBRARY code, you'll have a global variable named hello.


ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
Compilable compilable = ((Compilable) engine);

// Process LIBRARY code
Bindings bindings = new SimpleBindings();
engine.eval(LIBRARY, bindings);

// Compile SCRIPT code
CompiledScript actualScript = compilable.compile(SCRIPT);

// Run SCRIPT code
bindings.put("foo", "world");
Object result = actualScript.eval(bindings);
System.out.println(result);

Output

Hello world

Upvotes: 2

Related Questions