Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
4.0.18
-
None
-
None
Description
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):
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}") }
The same script worked as I expected in Groovy 3.x, but, in Groovy 4.0.18, it fails with the following error:
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)
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?