I've encountered what seems like bug introduced in Java 9 where variables can be leaked by the engine across separate contexts. I've extracted this minimal reproduction out of service I'm running in projection in Java 8. Gist: https://gist.github.com/also/412ce859f10f0b501bbfc43d15342dfc
Given this script var x; function test() { x = 1; print(++test.calls); eval(''); } test.calls = 0; test(); Repeatedly running it with a new context in the same engine works fine in Java 8 (it will print "1" forever), but in Java 9+, things get weird. I tested on macOS in openjdk 12.0.2 2019-07-16 from Oracle. ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); for (int i = 0; i < 20; i++) { SimpleScriptContext context = new SimpleScriptContext(); Bindings bindings = engine.createBindings(); context.setBindings(bindings, ScriptContext.ENGINE_SCOPE); engine.eval(script, context); } This logs 1 2 3 4 ... If you add a second `engine.eval(script, context);` to the loop, it starts to look like an optimization bug: 1 1 2 NaN 1 1 2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 2 1 2 1 2 1 It seems to stabilize on 2, 1 after the 18th iteration. With a third call to "engine.eval(script, context);" in the loop, it settles sooner: 1 1 1 2 NaN NaN 1 1 1 1 1 1 It works as expected if you omit `context` in the calls to `engine.eval()`, if you omit the `x = 1;` or `eval('');` lines in the `test` function, if you call `print(++test.calls);` before `x = 1;`, or when using the "graal.js" engine. I know GraalVM JS is probably the way forward here, but was hoping I'd be able to upgrade to Java 12 before making the switch.