groovy icon indicating copy to clipboard operation
groovy copied to clipboard

GROOVY-8096 setScriptBaseClass with Java class breaks @Field Binding init due to call to super() instead of super(Binding)

Open kreiger opened this issue 8 years ago • 3 comments

This test fails because ClassNode.getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) doesn't see the constructors in the Java base class.

ModuleNode.setScriptBaseClassFromConfig(ClassNode) calls .setSuperClass(ClassHelper.make(baseClassName)) on the scriptDummy ClassNode.

The ClassNode created for this script's base class has .lazyInitDone = true and .constructors = null so when .getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) is called by ModuleNode.createStatementsClass(), then ClassNode.constructors is set to an empty ArrayList in ClassNode.getDeclaredConstructors()

The script constructor is then generated as

     Constructor(Binding context) {
         super();                   // Fields are initialized after the call to super()
                                    // Fields are initialized here
         setBinding(context);       // Fields are initialized before the call to setBinding(context)
     }

instead of

     Constructor(Binding context) {
         super(context);            // Fields are initialized after the call to super(context)
     }

Fields are initialized between the call to super() and the setBinding(context) which means Field initializers don't have access to the Binding context.

This leads to MissingPropertyException because we're trying to look up variables from the new Binding() created in the default constructor, instead of the binding we passed in.

kreiger avatar Feb 22 '17 01:02 kreiger

Created JIRA ticket at https://issues.apache.org/jira/browse/GROOVY-8096

kreiger avatar Feb 22 '17 10:02 kreiger

Just to clarify - this isn't a PR designed to fix a problem (although BindingScript might prove useful in a solution) but to illustrate a problem. Correct?

paulk-asert avatar Feb 28 '17 10:02 paulk-asert

@paulk-asert Correct, this just adds a couple of unit tests to illustrate the problem. I hope you agree that it's better than just describing it. :)

I was able to make a patch myself where i use Class.forName() to look up the class, but i highly doubt it is correct.

kreiger avatar Mar 03 '17 13:03 kreiger