Caching and re-using bindings

Edmond Kemokai ekemokai at gmail.com
Tue Dec 6 13:56:44 UTC 2016


I doubt there is a problem, you're probably making a minor error. I am the
developer of HiveMind, it is a web app platform that relies entirely on
scripting engines. It doesn't cache bindings but rather caches the engine
and creates a new binding to handle every request.

You can access a demo instance: http://demo.crudzilla.com:7000/
Login with: developer/developer

I have created a test file in: /com/crudzilla/cloudTest/web/binding-test.ste

Put your code in there and save, I'll take a look to see what might be
missing.




On Tue, Dec 6, 2016 at 8:04 AM, yikes aroni <yikesaroni at gmail.com> wrote:

> Hmm.... it works if i instantiate the SimpleBinding obj and then putAll
> the bindings from the original bindings obj.
>
> Bindings bSimple = new SimpleBindings();
> bSimple.putAll(bEngine);
>
> Otherwise they either remain the same object or are bound in some way s.t.
> changes to bEngine are in bSimple. This just seems strange to me. Still
> curious to know what the reason for this is, despite having found a
> workaround.
>
>
>
> On Tue, Dec 6, 2016 at 7:59 AM, yikes aroni <yikesaroni at gmail.com> wrote:
>
>> Thanks for your response Edmond -- the problem is that a simplebindings
>> object still gets all the changes to the original bindings.... see below:
>>
>> // put variable globalA into the ScriptContext.ENGINE_SCOPE bindings
>> se.eval("globalA = 'testA';");
>> // Snapshot the bindings from the engine.
>> Bindings bEngine = se.getBindings(ScriptContext.ENGINE_SCOPE );
>> // print the bindings to confirm there is only one variable in them. -->
>> TRUE
>> printBindings(bEngine);
>> ------------------------
>> globalA = testA
>> // At this point there is only 'globalA' in the bindings so instantiate
>> simplebindings:
>> Bindings bSimple = new SimpleBindings(bEngine);
>> // Verify by printing the bindings
>> printBindings(bSimple);
>> ------------------------
>> globalA = testA
>> // put variable globalB into the ScriptContext.ENGINE_SCOPE bindings
>> se.eval("globalB = 'testB';");
>> // print the bindings. Now both variables are present........... WHY???
>> printBindings(bEngine);
>> ------------------------
>> globalA = testA
>> globalB = testB
>> // But look -- they are in the simple bindings obj as well!
>> printBindings(bSimple);------------------------
>> globalA = testA
>> globalB = testB
>>
>> That's precisely what i don't get --> Why are variables added to the
>> engine bindings *after* instantiating the simpleBindings showing up in the
>> simpleBindings object?
>>
>> And how do i avoid that?
>>
>> thanks
>>
>> On Mon, Dec 5, 2016 at 3:01 PM, Edmond Kemokai <ekemokai at gmail.com>
>> wrote:
>>
>>> Why don't you create instances of SimpleBinding and use those as needed?
>>> Use ScriptEngine.setBindings to reset the binding...
>>>
>>> On Dec 5, 2016 1:36 PM, "yikes aroni" <yikesaroni at gmail.com> wrote:
>>>
>>>> I want to cache ScriptEngine bindings for reuse. The basic algo would be
>>>>
>>>> 1) Build up my ScriptEngine (SE) with stuff i need.
>>>> 2) Snapshot the bindings -- i.e., cache them
>>>> Use engine.getBindings(ScriptContext.ENGINE_SCOPE)
>>>> 3) Use the SE for stuff that might modify its state.
>>>> 4) When done, replace the SE's bindings with my snapshotted bindings
>>>> Use engine.setBindings(_bindings_, ScriptContext.ENGINE_SCOPE)
>>>> 5) I now have a "fresh" SE to use.
>>>>
>>>> The problem is that this doesn't work as expected. The cached bindings
>>>> appear to point to the actual SE bindings and therefore whatever gets
>>>> added
>>>> to the SE bindings, also gets added to the cached bindings. Here's some
>>>> code to show how it's not doing what i would expect.
>>>>
>>>> public class TempEngineTest {
>>>>
>>>> static ScriptEngineManager seManager = new ScriptEngineManager();
>>>> static ScriptEngine se = seManager.getEngineByName("nashorn");
>>>> public static void printBindings(Map<String, Object> bindings) {
>>>> for (Map.Entry<String, Object> entry : bindings.entrySet()) {
>>>>    System.out.println(entry.getKey() + " = " + entry.getValue());
>>>> }
>>>> }
>>>> public static void main(String[] a) throws Exception {
>>>> // put variable globalA into the ScriptContext.ENGINE_SCOPE bindings
>>>> se.eval("globalA = 'testA';");
>>>> // Snapshot the bindings from the engine.
>>>> Bindings bEngine = se.getBindings(ScriptContext.ENGINE_SCOPE );
>>>> // print the bindings to confirm there is only one variable in them. -->
>>>> TRUE
>>>> printBindings(bEngine);
>>>> // put variable globalB into the ScriptContext.ENGINE_SCOPE bindings
>>>> se.eval("globalB = 'testB';");
>>>> // print the bindings. Now both variables are present........... WHY???
>>>> printBindings(bEngine);
>>>> }
>>>> }
>>>>
>>>> I've seen suggestions to cache and reuse bindings in various articles,
>>>> but
>>>> no specific code for doing so. How do i accomplish this in actual code?
>>>>
>>>> thanks
>>>>
>>>
>>
>


More information about the nashorn-dev mailing list