Hi Hannes, thanks for the explanations! The Javascript function being a closure over the scope it was evaluated in is exactly what I did not understand yet.
As the function object is dynamically created within some 3rd party Javascript that I cannot modify, I’m not able to create a CompiledScript instead. Just for some nit-picking, my test was able to call the function without placing it in parenthesis (the error message was '"foo" is not defined‘, so execution did enter the function, even though it does not find „foo“ because that wasn't defined in its closure). So it seems that the function declaration does not evaluate to undefined, at least not when evaluating it using engine.eval() from Java. Thanks again, Jörg Am 30.01.2017 um 18:52 schrieb Hannes Wallnöfer <hannes.wallnoe...@oracle.com<mailto:hannes.wallnoe...@oracle.com>>: There are a few problems with this code. The first is that a function declaration evaluates as undefined in Javascript, so your jsFunction variable is null. One way to work around this is to make the function an expression, e.g. by wrapping it in parentheses: engine.eval(„function test() { }“); // returns null but defines function „test" engine.eval(„(function test() { })“); // returns the function but doesn’t define it in scope Another issue is that Nashorn cannot directly use the default Binding implementation used by SimpleScriptContext. You should create a native Nashorn global object using engine.createBindings() as described in http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/api.html ScriptContext newContext = new SimpleScriptContext(); newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE); However, even with these issues fixed the problem remains that JavaScript functions are closures over the scope they were evaluated in. An evaluated function is always bound to the global object it was evaluated in. You can use the Compilable interface (as you did in your code) to create a compiled version of a script that will run with multiple globals: ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); CompiledScript compiledScript = ((Compilable) engine).compile("function test() {return foo;}; test();“); ScriptContext context = new SimpleScriptContext(); context.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); context.setAttribute("foo", "bar", ScriptContext.ENGINE_SCOPE); Object result = compiledScript.eval(context); Hannes Am 30.01.2017 um 11:28 schrieb Frantzius, Jörg <joerg.frantz...@aperto.com<mailto:joerg.frantz...@aperto.com>>: Hi, in my code, I get hold of a function object from some 3rd party Javascript code, and I need to execute that function within a new context, i.e. make new ENGINE_SCOPE bindings available to it. ScriptObjectMirror.call() unfortunately does not allow to define a context to execute in, so I tried to workaround by calling the function from a CompiledScript that in turn can be executed with a custom context: @Test public void testJsFunctionWithContext() throws ScriptException { ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); jdk.nashorn.api.scripting.ScriptObjectMirror jsFunction = (ScriptObjectMirror) engine.eval("function test() {return foo;}"); ScriptContext context = new SimpleScriptContext(); context.setAttribute("foo", "bar", ScriptContext.ENGINE_SCOPE); context.setAttribute("fn", jsFunction, ScriptContext.ENGINE_SCOPE); // does work: access context directly CompiledScript contextWrapper = ((Compilable) engine).compile("foo"); String result = (String) contextWrapper.eval(context); assertEquals("bar", result); // does not work: access context from within function ("foo" is not defined) contextWrapper = ((Compilable) engine).compile("fn()"); result = (String) contextWrapper.eval(context); assertEquals("bar", result); } Is there some mistake I made here, or is it simply not possible for a function object to access variables from a new context? If that’s really not possible, is there maybe a way of turning a function object into a CompiledScript object, which can then be evaluated with a new context? Thanks for any help, Jörg --- Dipl. Inf. Jörg von Frantzius, Technical Director E-Mail joerg.frantz...@aperto.com<mailto:joerg.frantz...@aperto.com> Phone +49 30 283921-318 Fax +49 30 283921-29 Aperto GmbH – An IBM Company Chausseestraße 5, D-10115 Berlin http://www.aperto.com<http://www.aperto.de/> http://www.facebook.com/aperto https://www.xing.com/companies/apertoag HRB 77049 B, AG Berlin Charlottenburg Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon --- Dipl. Inf. Jörg von Frantzius, Technical Director E-Mail joerg.frantz...@aperto.com Phone +49 30 283921-318 Fax +49 30 283921-29 Aperto GmbH – An IBM Company Chausseestraße 5, D-10115 Berlin http://www.aperto.com<http://www.aperto.de/> http://www.facebook.com/aperto https://www.xing.com/companies/apertoag HRB 77049 B, AG Berlin Charlottenburg Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon