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