You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2017/02/01 23:17:53 UTC
[jira] [Closed] (GROOVY-7301) Closure method gets successfully
called on the both delegate and the owner
[ https://issues.apache.org/jira/browse/GROOVY-7301?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King closed GROOVY-7301.
-----------------------------
> Closure method gets successfully called on the both delegate and the owner
> --------------------------------------------------------------------------
>
> Key: GROOVY-7301
> URL: https://issues.apache.org/jira/browse/GROOVY-7301
> Project: Groovy
> Issue Type: Bug
> Components: Compiler
> Affects Versions: 2.3.7
> Reporter: Andrew Audibert
> Assignee: Jochen Theodorou
> Labels: usertask
>
> If a MissingMethodException occurs during the execution of a delegate's closure, the ClosureMetaClass will incorrectly try to execute the method on the owner.
> {{test.groovy}}
> {code}
> def count = 0
> def delegate = {}
> delegate.f = {
> println "Successfully called f on the delegate"
> count += 1
> throw new MissingMethodException("f", String.class, [])
> }
> class Owner{}
> Owner.metaClass.invokeMethod = {name, args ->
> println "Successfully called f on the owner"
> count +=1
> }
> def a = {}
> a.delegate = delegate
> a.@owner = new Owner()
> a.setResolveStrategy(Closure.DELEGATE_FIRST)
> a.f()
> println count
> {code}
> Expected: Prints "Successfully called f on the delegate" and then throws a MissingMethodException.
> Actual:
> {code}
> aaudibert-mbp% groovy test.groovy
> Successfully called f on the delegate
> Successfully called f on the owner
> 2
> {code}
> The issue seems to be in ClosureMetaClass.invokeOnDelegationObjects where it does this:
> {code}
> try {
> return go.invokeMethod(methodName, args);
> } catch (MissingMethodException mme) {
> first = mme;
> } catch (GroovyRuntimeException gre) {
> Throwable th = unwrap(gre);
> if ((th instanceof MissingMethodException)
> && (methodName.equals(((MissingMethodException) th).getMethod()))) {
> first = (MissingMethodException) th;
> } else {
> throw gre;
> }
> }
> {code}
> Invoking the method and checking for MissingMethodException isn't enough to determine whether the method exists for the {{go}} object, because it may exist, but have the effect of throwing MME. The handling for GroovyRuntimeException is better, but still inadequate for determining whether the method exists on the {{go}} object, as shown by the repro.
> Would {{go.getMetaClass().pickMethod(methodName, ARG_TYPES)}} be the right way to do this?
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)