diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java index a93a0677f..2907094d1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/HippyMethodInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 the original author or authors. + * Copyright 2006-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,41 +36,35 @@ public class HippyMethodInvoker extends MethodInvoker { protected Method findMatchingMethod() { String targetMethod = getTargetMethod(); Object[] arguments = getArguments(); - int argCount = arguments.length; Method[] candidates = ReflectionUtils.getAllDeclaredMethods(getTargetClass()); int minTypeDiffWeight = Integer.MAX_VALUE; Method matchingMethod = null; Object[] transformedArguments = null; - int transformedArgumentCount = 0; - for (int i = 0; i < candidates.length; i++) { - Method candidate = candidates[i]; + for (Method candidate : candidates) { if (candidate.getName().equals(targetMethod)) { Class[] paramTypes = candidate.getParameterTypes(); Object[] candidateArguments = new Object[paramTypes.length]; int assignedParameterCount = 0; - boolean assigned = paramTypes.length==0; - for (int j = 0; j < arguments.length; j++) { - for (int k = 0; k < paramTypes.length; k++) { + for (Object argument : arguments) { + for (int i = 0; i < paramTypes.length; i++) { // Pick the first assignable of the right type that // matches this slot and hasn't already been filled... - if (ClassUtils.isAssignableValue(paramTypes[k], arguments[j]) && candidateArguments[k] == null) { - candidateArguments[k] = arguments[j]; + if (ClassUtils.isAssignableValue(paramTypes[i], argument) && candidateArguments[i] == null) { + candidateArguments[i] = argument; assignedParameterCount++; - assigned = true; break; } } } - if (assigned && paramTypes.length <= argCount) { + if (paramTypes.length == assignedParameterCount) { int typeDiffWeight = getTypeDifferenceWeight(paramTypes, candidateArguments); if (typeDiffWeight < minTypeDiffWeight) { minTypeDiffWeight = typeDiffWeight; matchingMethod = candidate; transformedArguments = candidateArguments; - transformedArgumentCount = assignedParameterCount; } } } @@ -80,11 +74,6 @@ public class HippyMethodInvoker extends MethodInvoker { throw new IllegalArgumentException("No matching arguments found for method: " + targetMethod); } - if (transformedArgumentCount < transformedArguments.length) { - throw new IllegalArgumentException("Only " + transformedArgumentCount + " out of " - + transformedArguments.length + " arguments could be assigned."); - } - setArguments(transformedArguments); return matchingMethod; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/HippyMethodInvokerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/HippyMethodInvokerTests.java index 0f62c039f..f675bfb62 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/HippyMethodInvokerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/HippyMethodInvokerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2012 the original author or authors. + * Copyright 2010-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ public class HippyMethodInvokerTests { HippyMethodInvoker invoker = new HippyMethodInvoker(); invoker.setTargetMethod("duplicate"); invoker.setTargetObject(new PlainPojo()); - invoker.setArguments(new Object[] { "2", "foo" }); + invoker.setArguments("2", "foo"); invoker.prepare(); assertEquals("foo.2", invoker.invoke()); } @@ -95,12 +95,39 @@ public class HippyMethodInvokerTests { assertEquals(target.foo(arg), Set.class); invoker.setTargetObject(target); - invoker.setArguments(new Object[] { arg }); + invoker.setArguments(arg); invoker.prepare(); assertEquals(invoker.invoke(), Set.class); } + @Test + public void testOverloadedMethodWithTwoArgumentsAndOneExactMatch() throws Exception { + + HippyMethodInvoker invoker = new HippyMethodInvoker(); + invoker.setTargetMethod("foo"); + @SuppressWarnings("unused") + class OverloadingPojo { + public Class foo(String arg1, Number arg2) { + return Number.class; + } + public Class foo(String arg1, List arg2) { + return List.class; + } + } + + String exactArg = "string"; + Integer inexactArg = 0; + OverloadingPojo target = new OverloadingPojo(); + assertEquals(target.foo(exactArg, inexactArg), Number.class); + + invoker.setTargetObject(target); + invoker.setArguments(exactArg, inexactArg); + invoker.prepare(); + assertEquals(invoker.invoke(), Number.class); + + } + public static class PlainPojo { public String handle(double value, String input) { return value + "." + input;