Search code examples
groovygroovyshell

Can GroovyShell binding pass a reference to object when doing setVariable?


I'm wondering if there's a way for Binding object to store reference to an object, instead of copying one?

Binding b = new Binding()
String test = "test"
b.setVariable("sth", test)
test = "blah"
GroovyShell gs = new GroovyShell(b)
gs.evaluate("print(sth)")

Unfortunately it prints "test".

Is there a way to do it in groovy?

EDIT:

the example I gave was wrong and way too simple.

I think my problem occurs because I instantiate object in one thread and run the script in another.

class Test {


[...] // field declarations

    public Test(String name, String url, def params, String validateScript, String afterTestScript, GroovyShell shell) {

[...] //just assigning params to fields

        shell.setVariable("current", this)
    }


    void action() {


       response = "something"

    }

    void validate() {
        //shell.setVariable("current", this)
    }

    void afterTest() {
        if (afterTestScript) shell.evaluate(afterTestScript)
    }

}

So the Test object is created in one Thread, and then I pass it as a reference to a Runnable object, which then calls action, validate and afterTest methods. If I comment out the call to setVariable in constructor and uncomment the call in validate it will work fine.

Is it possible it's a concurrency 'issue'? In the afterTestScript I just want to print the response string.


Solution

  • I was getting this when creating new threads on my own. Once I started to use a thread pool the problem went away.

    It is quite possible, that it was because of some other change, but this is the only change I could see interfering with groovy shell.

    In the end we stopped using groovy shell to evaluate strings and started to parse them into scripts to run them. This was a huge performance gain.