Index: src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaMethod.java =================================================================== --- src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaMethod.java (revision 13802) +++ src/main/org/codehaus/groovy/runtime/metaclass/ClosureMetaMethod.java (working copy) @@ -99,7 +99,8 @@ Class ownerClass = (Class) (owner instanceof Class ? owner : owner.getClass()); for (CachedMethod method : ReflectionCache.getCachedClass(ownerClass).getMethods() ) { if (method.getName().equals(methodClosure.getMethod())) { - res.add(new MethodClosureMetaMethod(name, declaringClass, closure, method)); + MetaMethod metaMethod = new MethodClosureMetaMethod(name, declaringClass, closure, method); + res.add(adjustParamTypesForStdMethods(metaMethod, name)); } } } @@ -107,40 +108,53 @@ if (closure instanceof GeneratedClosure) { for (CachedMethod method : ReflectionCache.getCachedClass(closure.getClass()).getMethods() ) { if (method.getName().equals("doCall")) { - res.add(new ClosureMetaMethod(name, declaringClass, closure, method)); + MetaMethod metaMethod = new ClosureMetaMethod(name, declaringClass, closure, method); + res.add(adjustParamTypesForStdMethods(metaMethod, name)); } } } else { - res.add(new MetaMethod(closure.getParameterTypes()){ - public int getModifiers() { - return Modifier.PUBLIC; - } - - public String getName() { - return name; - } - - public Class getReturnType() { - return Object.class; - } - - public CachedClass getDeclaringClass() { - return ReflectionCache.getCachedClass(declaringClass); - } - - public Object invoke(Object object, Object[] arguments) { - Closure cloned = (Closure) closure.clone(); - cloned.setDelegate(object); - arguments = coerceArgumentsToClasses(arguments); - return InvokerHelper.invokeMethod(closure, "call", arguments); - } - }); + MetaMethod metaMethod = + new MetaMethod(closure.getParameterTypes()){ + public int getModifiers() { + return Modifier.PUBLIC; + } + + public String getName() { + return name; + } + + public Class getReturnType() { + return Object.class; + } + + public CachedClass getDeclaringClass() { + return ReflectionCache.getCachedClass(declaringClass); + } + + public Object invoke(Object object, Object[] arguments) { + Closure cloned = (Closure) closure.clone(); + cloned.setDelegate(object); + arguments = coerceArgumentsToClasses(arguments); + return InvokerHelper.invokeMethod(closure, "call", arguments); + } + }; + res.add(adjustParamTypesForStdMethods(metaMethod, name)); } } return res; } + private static MetaMethod adjustParamTypesForStdMethods(MetaMethod metaMethod, String methodName) { + Class[] nativeParamTypes = metaMethod.getNativeParameterTypes(); + nativeParamTypes = (nativeParamTypes != null) ? nativeParamTypes : new Class[0]; + if("methodMissing".equals(methodName) && + nativeParamTypes.length == 2 && nativeParamTypes[0] != String.class) { + nativeParamTypes[0] = String.class; + } + return metaMethod; + } + public CachedMethod getDoCall() { return doCall; }