[ https://issues.apache.org/jira/browse/GROOVY-11211?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Eric Milles updated GROOVY-11211: --------------------------------- Description: 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:java} 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:java} 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} java.lang.Exception: Missing key: foo {code} This code works as expected with Groovy 3.x was: 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:java} 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:java} 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} java.lang.Exception: Missing key: foo {code} This code works as expected with Groovy 3.x > 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:java} > 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:java} > 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} > 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)