As Hannes stated, you can use the lower-level CompiledScript directly, and avoid this "pollution", as you call it.

The problem with ScriptEngine (JSR-223) is that it simply doesn't specify threading behavior, so you can't fault the Nashorn team for not adhering to a non-existent spec. If you look around at JSR-223 implementations of other language engines, you'll find a variety of (incompatible) approaches to the problem of threading. I think JSR-223 is simply not a good solution for concurrent applications (unless the implementation for a particular engine does the "right thing" in terms of your expectations).

Sorry for self-advertising, but I do think it's relevant: this is exactly the reason why I created Scripturian as an alternative to JSR-223:

http://threecrickets.com/scripturian/

The idea was to have a very strictly defined threading model for all engines, exactly so that you can embed them in high-concurrency applications. In some cases this proved impossible: Scala and Kotlin cannot be supported, it seems, do to their reliance on global singletons. But Nashorn, Rhino, Groovy, Quercus (PHP), Luaj, Jython, JRuby, Velocity and Succinct are.

Note, though, that for Nashorn you want to use a recent build from the Mercurial repository. Also note that since Nashorn does not, at this point, support caching of compiled code to disk, this Scripturian feature is not supported for Nashorn. The consequence is that Nashorn applications have a *very* slow start-up as compared to other engines, as it needs to compiled all the code, though once it is up and running performance is generally excellent.

On 10/30/2014 10:03 PM, Benjamin Sieffert wrote:
Hello there,

we had a similar aim / similar issues with nashorn. Since I don't know your
code exactly, I'll just describe our case / what we ended up doing and
maybe you can get some ideas off that.

We use one ScriptEngine. Among all our threads, just one engine. On
start-up we let it compile the library once. The library has no mutable
state and is not dependant on global variables. It's just a collection of
functions / classes.
Then we have a few hundred small javascripts that basically instantiate a
class defined by the library and do some configurations on that instance.
Any one of these scripts gets evaluated by the engine once and the returned
ScriptObjectMirror (the configured javascript object) is then kept on the
java side. As this ScriptObjectMirror also does not have any mutable state,
we can now safely use it among multiple threads via callMember().
To get nice stack traces, we also wrap each small javascript into a
load()-call in the engine and name it. The library is also wrapped in a
load()-call.

All approaches including some sort of mutable javascript-side state sadly
do not seem to be workable. The nashorn devs have (understandably)
explicitly stated that since javascript does not define multithreaded
semantics, they will not be implementing any.
Everything evaluated in a NashornScriptEngine keeps its original
context/global, even when seemingly "put" into another engine. You cannot
prevent pollution. I tried for some time. : )


Reply via email to