[
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)