From the website docs:
The Rhino Context object is used to store thread-specific information about the execution environment. There should be one and only one Context associated with each thread that will be executing JavaScript.
In other words, do not pass the context between threads. Just create a new context in the running thread. Don't worry about calling Context.enter()
more than once within a thread. They are effectively thread-local variables that are internally reference-counted. So calling Context.enter()
in the same thread is very light.
Again from the docs:
These calls will work properly even if there is already a Context associated with the current thread. That context will be returned and an internal counter incremented. Only when the counter reaches zero will it be disassociated from the thread.
Personally, I just used this code construct everywhere:
Context ctx = Context.enter();
try {
// do something with the ctx
} finally {
Context.exit();
}
In fact, in Groovy I whipped together this:
def withContext(Closure closure) {
Context ctx = Context.enter();
try {
closure.call(ctx);
} finally {
Context.exit();
}
}
and then pass it code like the following:
withContext { Context ctx ->
ScriptableObject scope = ctx.initStandardObjects()
// now to do work with the scope and ctx.
}
One final note. The scope is not tied to the context, and can be persisted/passed between threads.