From 03be8095ca105714ffb3dfbbe3c5a7bee6b6ff83 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 16 Oct 2017 15:34:18 +0200 Subject: [PATCH] Consistent handling of null array for arguments Issue: SPR-16075 (cherry picked from commit c29b6f5) --- .../MethodInvokingFactoryBeanTests.java | 34 +++++++++---------- .../springframework/util/MethodInvoker.java | 4 +-- .../util/MethodInvokerTests.java | 32 +++++++++++------ 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/config/MethodInvokingFactoryBeanTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/config/MethodInvokingFactoryBeanTests.java index 4d5b39e569e..8d0786bada5 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/config/MethodInvokingFactoryBeanTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/config/MethodInvokingFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -140,7 +140,7 @@ public class MethodInvokingFactoryBeanTests { mcfb.setTargetMethod("voidRetvalMethod"); mcfb.afterPropertiesSet(); Class objType = mcfb.getObjectType(); - assertTrue(objType.equals(void.class)); + assertSame(objType, void.class); // verify that we can call a method with args that are subtypes of the // target method arg types @@ -148,7 +148,7 @@ public class MethodInvokingFactoryBeanTests { mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes"); - mcfb.setArguments(new Object[] {new ArrayList(), new ArrayList(), "hello"}); + mcfb.setArguments(new ArrayList<>(), new ArrayList(), "hello"); mcfb.afterPropertiesSet(); mcfb.getObjectType(); @@ -157,7 +157,7 @@ public class MethodInvokingFactoryBeanTests { mcfb.registerCustomEditor(String.class, new StringTrimmerEditor(false)); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes"); - mcfb.setArguments(new Object[] {"1", new Object()}); + mcfb.setArguments("1", new Object()); try { mcfb.afterPropertiesSet(); fail("Should have thrown NoSuchMethodException"); @@ -225,7 +225,7 @@ public class MethodInvokingFactoryBeanTests { mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes"); - mcfb.setArguments(new Object[] {new ArrayList(), new ArrayList(), "hello"}); + mcfb.setArguments(new ArrayList<>(), new ArrayList(), "hello"); // should pass mcfb.afterPropertiesSet(); } @@ -235,7 +235,7 @@ public class MethodInvokingFactoryBeanTests { MethodInvokingFactoryBean mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes"); - mcfb.setArguments(new Object[] {new ArrayList(), new ArrayList(), "hello", "bogus"}); + mcfb.setArguments(new ArrayList<>(), new ArrayList(), "hello", "bogus"); try { mcfb.afterPropertiesSet(); fail("Matched method with wrong number of args"); @@ -247,7 +247,7 @@ public class MethodInvokingFactoryBeanTests { mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes"); - mcfb.setArguments(new Object[] {1, new Object()}); + mcfb.setArguments(1, new Object()); try { mcfb.afterPropertiesSet(); mcfb.getObject(); @@ -260,14 +260,14 @@ public class MethodInvokingFactoryBeanTests { mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes2"); - mcfb.setArguments(new Object[] {new ArrayList(), new ArrayList(), "hello", "bogus"}); + mcfb.setArguments(new ArrayList<>(), new ArrayList(), "hello", "bogus"); mcfb.afterPropertiesSet(); assertEquals("hello", mcfb.getObject()); mcfb = new MethodInvokingFactoryBean(); mcfb.setTargetClass(TestClass1.class); mcfb.setTargetMethod("supertypes2"); - mcfb.setArguments(new Object[] {new ArrayList(), new ArrayList(), new Object()}); + mcfb.setArguments(new ArrayList<>(), new ArrayList(), new Object()); try { mcfb.afterPropertiesSet(); fail("Matched method when shouldn't have matched"); @@ -292,14 +292,14 @@ public class MethodInvokingFactoryBeanTests { ArgumentConvertingMethodInvoker methodInvoker = new ArgumentConvertingMethodInvoker(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArgument"); - methodInvoker.setArguments(new Object[] {5}); + methodInvoker.setArguments(5); methodInvoker.prepare(); methodInvoker.invoke(); methodInvoker = new ArgumentConvertingMethodInvoker(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArgument"); - methodInvoker.setArguments(new Object[] {"5"}); + methodInvoker.setArguments(5); methodInvoker.prepare(); methodInvoker.invoke(); } @@ -309,37 +309,37 @@ public class MethodInvokingFactoryBeanTests { MethodInvokingBean methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new Object[]{new Integer[] {5, 10}}); + methodInvoker.setArguments(new Object[] {new Integer[] {5, 10}}); methodInvoker.afterPropertiesSet(); methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new Object[]{new String[]{"5", "10"}}); + methodInvoker.setArguments(new Object[] {new String[] {"5", "10"}}); methodInvoker.afterPropertiesSet(); methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new Object[]{new Integer[] {5, 10}}); + methodInvoker.setArguments(new Object[] {new Integer[] {5, 10}}); methodInvoker.afterPropertiesSet(); methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new String[]{"5", "10"}); + methodInvoker.setArguments("5", "10"); methodInvoker.afterPropertiesSet(); methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new Object[]{new Integer[] {5, 10}}); + methodInvoker.setArguments(new Object[] {new Integer[] {5, 10}}); methodInvoker.afterPropertiesSet(); methodInvoker = new MethodInvokingBean(); methodInvoker.setTargetClass(TestClass1.class); methodInvoker.setTargetMethod("intArguments"); - methodInvoker.setArguments(new Object[]{"5", "10"}); + methodInvoker.setArguments("5", "10"); methodInvoker.afterPropertiesSet(); } diff --git a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java index d940242fba9..e078b3be372 100644 --- a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java +++ b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java @@ -44,7 +44,7 @@ public class MethodInvoker { private String staticMethod; - private Object[] arguments = new Object[0]; + private Object[] arguments; /** The method we will call */ private Method methodObject; @@ -130,7 +130,7 @@ public class MethodInvoker { * Return the arguments for the method invocation. */ public Object[] getArguments() { - return this.arguments; + return (this.arguments != null ? this.arguments : new Object[0]); } diff --git a/spring-core/src/test/java/org/springframework/util/MethodInvokerTests.java b/spring-core/src/test/java/org/springframework/util/MethodInvokerTests.java index b90bf3b6dc7..58da336d0dd 100644 --- a/spring-core/src/test/java/org/springframework/util/MethodInvokerTests.java +++ b/spring-core/src/test/java/org/springframework/util/MethodInvokerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -49,18 +49,28 @@ public class MethodInvokerTests { Integer i = (Integer) mi.invoke(); assertEquals(1, i.intValue()); + // defensive check: singleton, non-static should work with null array + tc1 = new TestClass1(); + mi = new MethodInvoker(); + mi.setTargetObject(tc1); + mi.setTargetMethod("method1"); + mi.setArguments((Object[]) null); + mi.prepare(); + i = (Integer) mi.invoke(); + assertEquals(1, i.intValue()); + // sanity check: check that argument count matching works mi = new MethodInvoker(); mi.setTargetClass(TestClass1.class); mi.setTargetMethod("supertypes"); - mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello"}); + mi.setArguments(new ArrayList<>(), new ArrayList<>(), "hello"); mi.prepare(); assertEquals("hello", mi.invoke()); mi = new MethodInvoker(); mi.setTargetClass(TestClass1.class); mi.setTargetMethod("supertypes2"); - mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello", "bogus"}); + mi.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", "bogus"); mi.prepare(); assertEquals("hello", mi.invoke()); @@ -68,7 +78,7 @@ public class MethodInvokerTests { mi = new MethodInvoker(); mi.setTargetClass(TestClass1.class); mi.setTargetMethod("supertypes2"); - mi.setArguments(new Object[] {new ArrayList<>(), new ArrayList<>(), "hello", Boolean.TRUE}); + mi.setArguments(new ArrayList<>(), new ArrayList<>(), "hello", Boolean.TRUE); exception.expect(NoSuchMethodException.class); mi.prepare(); @@ -79,7 +89,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {"no match"}); + methodInvoker.setArguments("no match"); exception.expect(NoSuchMethodException.class); methodInvoker.prepare(); @@ -90,7 +100,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new Purchaser()}); + methodInvoker.setArguments(new Purchaser()); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("purchaser: hello", greeting); @@ -101,7 +111,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new Shopper()}); + methodInvoker.setArguments(new Shopper()); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("purchaser: may I help you?", greeting); @@ -112,7 +122,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new Salesman()}); + methodInvoker.setArguments(new Salesman()); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("greetable: how are sales?", greeting); @@ -123,7 +133,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new Customer()}); + methodInvoker.setArguments(new Customer()); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("customer: good day", greeting); @@ -134,7 +144,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new Regular("Kotter")}); + methodInvoker.setArguments(new Regular("Kotter")); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("regular: welcome back Kotter", greeting); @@ -145,7 +155,7 @@ public class MethodInvokerTests { MethodInvoker methodInvoker = new MethodInvoker(); methodInvoker.setTargetObject(new Greeter()); methodInvoker.setTargetMethod("greet"); - methodInvoker.setArguments(new Object[] {new VIP("Fonzie")}); + methodInvoker.setArguments(new VIP("Fonzie")); methodInvoker.prepare(); String greeting = (String) methodInvoker.invoke(); assertEquals("regular: whassup dude?", greeting);