Question

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.

Was it helpful?

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.

OTHER TIPS

The essence of your problem is actually due to the fact that your object reference is changed after setting it. if you want to change it after assigning it, then you'd need a wrapper object. E.g. instead of

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

Use

class MyWapper {
  public String myText
  public MyWrapper(String text){
   this.myText = text;
  }
}

MyWrapper test = new MyWrapper("test")
b.setVariable("sth", test)
test.myText = "blah"
GroovyShell gs = new GroovyShell(b)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top