Search code examples
multithreadingservletsnashorn

Nashorn: concurrent eval with singleton ScriptEngine ? thread safe?


We would like to use Nashorn within a servlet. The idea is to use a singleton instance of ScriptEngine that is reused at every request. At each request an new EngineScope Binding is created, and the eval is run with that binding. Then the binding is cleared. No shared objects are passed to the bindings (just the request/response objects from the servlet).

Within the servlets, the singleton instance of ScriptEngine may be eval-ed concurrently in different threads, will this work properly or will it run into a threading issue? Here is some code that gives the idea:

ScriptEngine engine = getNashornSingleton();

ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope =newContext.getBindings(ScriptContext.ENGINE_SCOPE);

engineScope.put("request", request);
engineScope.put("response", response);

engine.eval(jsCode, engineScope);
engineScope.clear();

Solution

  • My answer to my own question: I would not use a singleton as described above. Despite some potential threading issues, you likely do not want to destroy the bindings at each request (as it may require re-compiling of scripts). What we ended up doing is creating a pool of Engines and their associated scope Bindings. An engine/binding pair.

    At each servlet request we grab an engine/binding pair from the pool, put the request/response into the binding, and then execute the script. There is no threading issues to worry about because a given engine/binding pair is only executed by a single thread at a time. When the request is done, the engine/binding pair is returned to the pool. Seems to work well.