Hi, I'm developping a webapp that uses the rhino engine that comes with java 6 (using the JSR 223 api). I need to setup a shared ScriptContext at application startup (compilation is not an option here). I'm not sure how to do that (something similar to dynamic scopes[1], but in terms of the JSR 223). Is that even possible with the scripting API? If possible i'd prefer to not use rhino explicitly.
If i interpret correctly the results of the various experiments i've done, objects/functions put in GLOBAL_SCOPE can't see ENGINE_SCOPE'd objects. Is that correct? There's obviously something that i missing here so any help would be appreciated. For reference, and to make things more explicit, i attach below a testcase that reproduces the problem i'm facing. Thanks for your help! [1] http://mxr.mozilla.org/mozilla/source/js/rhino/examples/DynamicScopes.java SharedContextTest.java public class SharedContextTest extends TestCase { private ScriptEngine e = new ScriptEngineManager().getEngineByName("js"); interface ITest { int test(); } /** * This prints (line order is irrelevant) Thread-1: 4 Thread-0: 4 Thread-1: 4 Thread-0: 4 * * We expect (line order still irrelevant) Thread-1: 4 Thread-0: 10 Thread-1: 4 Thread-0: 10 */ public void testShare() throws Exception { //sharing engine or instantiating an engine per thread doesn't make any difference //ScriptEngine e = new ScriptEngineManager().getEngineByName("js"); ScriptContext sharedContext = new SimpleScriptContext(); sharedContext.setBindings(new SimpleBindings(), ScriptContext.GLOBAL_SCOPE); e.eval( "var A = function() { }; " + "A.prototype.test = function() { " + " var t = x + 5;" + " for ( u = 0; u < 3; u++ ) { " + " java.lang.System.out.println(java.lang.Thread.currentThread().getName() + ': ' + t); " + " java.lang.Thread.sleep(1000); " + " } " + " return t; " + "};", sharedContext.getBindings(ScriptContext.GLOBAL_SCOPE)); Thread t1 = new Thread(createRunnable(sharedContext, 5, "thread1")); Thread t2 = new Thread(createRunnable(sharedContext, -1, "thread2")); t1.start(); t2.start(); t1.join(); t2.join(); } private Runnable createRunnable(final ScriptContext sc, final int val, final String name) throws Exception { Runnable r = new Runnable() { @Override public void run() { //ScriptEngine e = new ScriptEngineManager().getEngineByName("rhino"); Bindings bindings = sc.getBindings(ScriptContext.GLOBAL_SCOPE); ScriptContext ctx = new SimpleScriptContext(); //if we use GLOBAL_SCOPE then we get an EcmaError: "x is not defined" at the line marked [invoke] below //if we use ENGINE_SCOPE x is put in the sharedContext bindings and is shared between threads (expected?) //instantiating a new SimpleBindings instead of directly referencing sharedContext.bindings[given scope] doesn't seem to make any difference (expected?) Bindings b = new SimpleBindings(bindings); ctx.setBindings(b, ScriptContext.ENGINE_SCOPE); ctx.setAttribute("x", val, ScriptContext.ENGINE_SCOPE); try { e.eval("var a = new A();", ctx); } catch (ScriptException e1) { e1.printStackTrace(); } Object atom = ctx.getAttribute("a", ScriptContext.ENGINE_SCOPE); ITest test = ((Invocable) e).getInterface(atom, ITest.class); Object o = test.test(); //do something with o } }; return r; } } _______________________________________________ dev-tech-js-engine-rhino mailing list [email protected] https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
