[ https://issues.apache.org/jira/browse/GROOVY-11211?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17781810#comment-17781810 ]
Eric Milles commented on GROOVY-11211: -------------------------------------- Before Groovy 4, {{ClosureMetaClass#invokeOnDelegationObjects}} directly called {{invokeMethod}} on the delegate. It now calls {{InvokerHelper.invokeMethod(theDelegate, methodName, args)}} which falls through to {{MetaClassImpl#invokePropertyOrMissing}}. There are two workarounds for your code: # add {{GroovyInterceptable}} as an implemented interface of {{Context}} # let {{get}} return null for "foo" and the logic will fall through to missing method handling which calls {{GroovyObject#invokeMethod}} > Unexpected invocation of getter method > -------------------------------------- > > Key: GROOVY-11211 > URL: https://issues.apache.org/jira/browse/GROOVY-11211 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime > Affects Versions: 4.0.15 > Reporter: paolo di tommaso > Assignee: Eric Milles > Priority: Minor > > The map {{get}} method is invoked unexpectedly while resolving a closure > delegate. > To replicate the issue consider the following custom Map object in which both > {{get}} and {{invokeMethod}} methods are overridden: > {code:groovy} > class Context implements Map<String,Object> { > @Delegate private Map<String,Object> target > Context(Map<String,Object> target) { this.target = target } > @Override > Object get(Object name) { > if( target.containsKey(name) ) > return target.get(name) > throw new Exception('Missing key: ' + name) > } > @Override > Object invokeMethod(String name, Object args) { > if( name == 'foo' ) > return 'OK' > else > super.invokeMethod(name, args) > } > } > {code} > > Then, a closure tries to invoke the {{foo}} method via a context delegate, as > shown below: > {code:groovy} > def closure = { it -> foo() } > closure.delegate = new Context([:]) > closure.setResolveStrategy(Closure.DELEGATE_ONLY) > assert closure.call() == 'OK' > {code} > > The "OK" string should be returned by the closure because {{foo}} method > should be resolved via the {{invokeMethod}} method. > > However, the above snippet fails with the following message: > {code} > java.lang.Exception: Missing key: foo > {code} > > This code works as expected with Groovy 3.x -- This message was sent by Atlassian Jira (v8.20.10#820010)