Relationship between "global" and "engine" scope
yikes aroni
yikesaroni at gmail.com
Mon Nov 3 20:25:13 UTC 2014
It appears that nashorn has named stuff in a non-intuitive way and I just
want to confirm that I understand things correctly. Ordinarily, I would
assume that "global" scope is a broader scope than "engine" scope, meaning
that anything defined in "global" scope would be available to the engine
scope. That would be great news! But i fear that it's not the case -- or at
least not in the specific way i'm trying to use it. Furthermore, it appears
that "engine" and "global" scope have no relationship to oneanother
whatsoever.
I'm attempting to evaluate a library in a ScriptEngine's "engine" scope
(call this engine "baseEngine"), then set baseEngine's engine scope to the
"global" scope for another ScriptEngine ("tempEngine"). Why would I want to
do that? So that I can do the expensive eval on my script once and reuse it
by shoving it into another script engine's scope. That is, I then eval some
script in tempEngine's "engine" scope and assume that the library I shoved
into tempEngine's "global" scope can be found and leveraged by the script.
This appears not to be the case. Consider this test code:
NashornScriptEngineFactory engineFactory = new
NashornScriptEngineFactory();
ScriptEngine baseEngine = engineFactory.getScriptEngine();
// Here's the script we ultimately want in the "global" scope of
tempEngine
String script = "var test = (function() {" + "var publ = {};"
+ "var priv = {};" + "publ.hello = function() {"
+ " print('hello ' + eval('nnn'));" + "};" + "return publ;"
+ "})();";
// Load the script into baseEngine's ENGINE bindings
baseEngine.eval(script);
// The "library" script is now in base engine's ENGINE scope. Get a
handle on ENGINE
// bindings to try to inject them...
Bindings engineScopeBase =
baseEngine.getBindings(ScriptContext.ENGINE_SCOPE);
// Get the tempEngine
ScriptEngine tempEngine = engineFactory.getScriptEngine();
// eval the variable 'nnn' into tempEngine's ENGINE scope
tempEngine.eval("var nnn = 'fellow';",
tempEngine.getBindings(ScriptContext.ENGINE_SCOPE));
// Explicitly set the bindings to the temp context.
// Comment out the first two lines to put the variable in global
scope and the script in engine scope
// Comment the 2nd two lines to put the variable in tempEngine's
ENGINE scope and the script in its GLOBAL scope
ScriptContext ctxTemp = new SimpleScriptContext();
ctxTemp.setBindings(engineScopeBase, ScriptContext.ENGINE_SCOPE);
ctxTemp.setBindings(tempEngine.getBindings(ScriptContext.ENGINE_SCOPE),
ScriptContext.GLOBAL_SCOPE);
//ctxTemp.setBindings(engineScopeBase, ScriptContext.GLOBAL_SCOPE);
//ctxTemp.setBindings(tempEngine.getBindings(ScriptContext.ENGINE_SCOPE),
ScriptContext.ENGINE_SCOPE);
System.out.println("is nnn in engine scope?: nnn="
+
ctxTemp.getBindings(ScriptContext.ENGINE_SCOPE).get("nnn"));
System.out.println("is nnn in global scope?: nnn="
+
ctxTemp.getBindings(ScriptContext.GLOBAL_SCOPE).get("nnn"));
System.out.println("is test in engine scope?: test="
+
ctxTemp.getBindings(ScriptContext.ENGINE_SCOPE).get("test"));
System.out.println("is test in global scope?: test="
+
ctxTemp.getBindings(ScriptContext.GLOBAL_SCOPE).get("test"));
tempEngine.eval("print(test.hello());", ctxTemp);
The output either looks like this:
is nnn in engine scope?: nnn=null
is nnn in global scope?: nnn=fellow
is test in engine scope?: test=[object Object]
is test in global scope?: test=null
or like this:
is nnn in engine scope?: nnn=fellow
is nnn in global scope?: nnn=null
is test in engine scope?: test=null
is test in global scope?: test=[object Object]
When the last line runs, I get the error
Exception in thread "main" javax.script.ScriptException:
ReferenceError: "nnn" is not defined in <eval>#1:95<eval>@0 at line number 1
In other words, the script can never find the variable 'nnn' -- not in the
global scope nor in the engine scope regardless of how i set up global /
engine bindings.
Is there any way to make this work? Before I give up, I want to make sure
that i'm not missing something and have exhausted all possibilities....
thanks!
More information about the nashorn-dev
mailing list