Tomás Crespo García created GROOVY-11313:
--------------------------------------------

             Summary: Closure owner seems to be overwritten
                 Key: GROOVY-11313
                 URL: https://issues.apache.org/jira/browse/GROOVY-11313
             Project: Groovy
          Issue Type: Bug
    Affects Versions: 4.0.18
            Reporter: Tomás Crespo García


I had a Groovy script with nested closures that used {{owner}} as the name of 
the outer closure's parameter (even though {{owner}} might conflict with the 
closure [owner|https://groovy-lang.org/closures.html#_owner_of_a_closure]):
{code:java}
import groovy.sql.GroovyRowResult
 
runAll()
 
void runAll() {
    List owners = [new GroovyRowResult([user_id: 1])]
    List pets = [new GroovyRowResult([id: 1])]
 
    owners.each { owner ->
        myMethod(1)
        pets.each { pet ->
            myMethod(2)
            println(owner.user_id)
        }
    }
}
 
void myMethod(int i) {
    println("Running my method ${i}")
} {code}
The same script worked as I expected in Groovy 3.x, but, in Groovy 4.0.18, it 
fails with the following error:
{code:java}
Exception in thread "main" groovy.lang.MissingPropertyException: No such 
property: myMethod for class: groovy.sql.GroovyRowResult
at groovy.sql.GroovyRowResult.getProperty(GroovyRowResult.java:55)
at groovy.sql.GroovyRowResult.get(GroovyRowResult.java:157)
at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1389)
at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
at 
org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
at 
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
at 
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:391)
at 
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:328)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
at 
org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
at Script1$_runAll_closure1$_closure2.doCall(Script1.groovy:16)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method)
at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328) {code}
It seems that {{myMethod}} in the inner closure is trying to get resolved as a 
property of {{{}GroovyRowResult{}}}, which is the type of the {{owner}} 
parameter of the outer closure. The moment I rename {{owner}} to something else 
or transform the inner {{each}} to a {{for}} loop, the script works. It doesn't 
fail either if I don't try to access any property of {{owner}} inside the inner 
closure (such as {{{}owner.user_id{}}}).
 
Is this expected? 
 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to