Valerii created GROOVY-9425:
-------------------------------

             Summary: InheritConstructors: child class use property value from 
base class in constructor despite have the same property
                 Key: GROOVY-9425
                 URL: https://issues.apache.org/jira/browse/GROOVY-9425
             Project: Groovy
          Issue Type: Question
    Affects Versions: 3.0.1
            Reporter: Valerii


Hi, I'm working on refactoring some Jenkins pipelines in Groovy, and stumbled 
upon some behaviour which looks strange for me.
 I've found a bunch of copy-pasted classes which had the same 
constructors/getter, and differs only in one class property value. I've created 
a base class for them, and used @groovy.transform.InheritConstructors directive 
to not have several same constructors. And here I've got a trouble: when 
calling one of constructors on child class, which accesses property defined on 
both classes, it takes property value from parent class.


 Here is the sample code:
{code:java}
class BaseClass
{
    public String JSON_KEY = "boolean_param"
    Boolean booleanValue
    def steps

    BaseClass(Boolean b = false) {
        this.booleanValue = b
    }

    BaseClass(steps, Map param) {
        this.steps = steps
        steps.println param.toString()
        steps.println this.JSON_KEY
        if (param[JSON_KEY] != null)
            this.booleanValue = param[JSON_KEY].toBoolean()
    }

    def get()
    {
        return booleanValue
    }
}

@groovy.transform.InheritConstructors
class ChildClass extends BaseClass
{
    final static public String JSON_KEY = "test_param"
}

BaseClass test1 = new BaseClass()
ChildClass test2 = new ChildClass(true)
println test1.get().toString()
println test2.get().toString()
println "-----------------"
map3 = [boolean_param: true]
test3 = new BaseClass(this, map3)
println test3.get()
println test3.JSON_KEY
println "-----------------"
map4 = [test_param: true]
test4 = new ChildClass(this, map4)
println test4.get()
println test4.JSON_KEY
{code}
 

Actual output (from either Groovy Playground or local Groovy install):
{code:java}
false
 true
 -----------------
 [boolean_param:true]
 boolean_param
 true
 boolean_param
 -----------------
 [test_param:true]
 boolean_param
 null
 test_param{code}

 Expected output:
{code:java}
false
 true
 -----------------
 [boolean_param:true]
 boolean_param
 true
 boolean_param
 -----------------
 [test_param:true]
 test_param
 true
 test_param{code}

 So, constructor with Boolean as input works as expected, but one with Map is 
using property from base class despite being called on child class.
 Could anybody please explain why I'm seeing this behaviour, and how to get the 
desired one? I'm not a developer, so I may miss something very basic here :)

Also, if I remove JSON_KEY from base class I'm getting confusing "No such 
property: JSON_KEY for class: ChildClass" exception

{code:java}
Caught: groovy.lang.MissingPropertyException: No such property: JSON_KEY for 
class: ChildClass
groovy.lang.MissingPropertyException: No such property: JSON_KEY for class: 
ChildClass
        at 
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:65)
        at 
org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:87)
        at 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:341)
        at BaseClass.<init>(test.groovy:13)
        at ChildClass.<init>(test.groovy)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown 
Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at 
org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
        at 
org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
        at 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
        at 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
        at 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:286)
        at test.run(test.groovy:41)
        at 
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:258)
        at groovy.lang.GroovyShell.run(GroovyShell.java:364)
        at groovy.lang.GroovyShell.run(GroovyShell.java:353)
        at groovy.ui.GroovyMain.processOnce(GroovyMain.java:652)
        at groovy.ui.GroovyMain.run(GroovyMain.java:398)
        at groovy.ui.GroovyMain.access$1400(GroovyMain.java:68)
        at groovy.ui.GroovyMain$GroovyCommand.process(GroovyMain.java:322)
        at groovy.ui.GroovyMain.processArgs(GroovyMain.java:142)
        at groovy.ui.GroovyMain.main(GroovyMain.java:115)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at 
org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:111)
        at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:129)
{code}




--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to