Reputation: 2684
I am writing a small Groovy DSL
, which relies on Groovy Closures
. I then run the DSL
from a Java
program by using GroovyShell
and a DelegatingScript
.
Code invoking the script from Java:
DelScript project = new DelScript ();
CompilerConfiguration cc = new CompilerConfiguration();
cc.setScriptBaseClass("groovy.util.DelegatingScript");
GroovyShell sh = new GroovyShell(Launcher.class.getClassLoader(), new Binding(), cc);
DelegatingScript script = (DelegatingScript) sh.parse(new File(path));
script.setDelegate(project);
script.run();
The instance of DelScript
works as the this
reference inside the script, e.g. any member or method not found in the script itself is searched in the instance of DelScript
.
My script can include the following expressions:
create (name: "test") {
// this code can be used to initialize the
// object that is created here
testProperty = "I'm an example"
}
The intention of this code is to create an object and then call the closure, which can be used to initialize it. As I said before, the create
method resides in the DelScript
instance, (which is what I want) and it looks like this:
def create(arguments, configClosure) {
// create new object
def x = new Impl(arguments)
// use configClosure to init it
configClosure.delegate = x
configClosure()
}
Although I set the delegate
of the configClosure
, I get an error that testProperty
is not a part of DelScript
. I know that the DelScript
instance is the this
of the configClosure
, since I created it in the DelScript
scope, but I thought that the closure would check references in the order: this -> owner -> delegate
. It never checks delegate
in my case but raises an exception right after checking this
.
Can anyone give me some feedback on what I am doing wrong?
Upvotes: 0
Views: 245
Reputation: 171084
After the line
configClosure.delegate = x
Put
configClosure.resolveStrategy = Closure.DELEGATE_FIRST
Upvotes: 1