package org.jgroups.tests; import org.jgroups.Address; import org.jgroups.Global; import org.jgroups.blocks.MethodCall; import org.jgroups.util.Util; import org.testng.Assert; import org.testng.annotations.Test; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * @author Bela Ban belaban@yahoo.com * @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a> **/ @Test(groups=Global.FUNCTIONAL) public class MethodCallTest { protected static final Method CALL; protected static final Map<Short,Method> methods=new HashMap<>(); static { try { CALL=MethodCallTest.class.getMethod("call", boolean.class, Boolean.class, int.class, double.class, float.class, byte[].class, String[].class); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } methods.put((short)1, CALL); try { methods.put((short)2, TargetClass.class.getMethod("foobar")); } catch(NoSuchMethodException e) { throw new IllegalStateException(e); } } public static class TargetClass { public static boolean foo(int a, String b) { System.out.println("test(" + a + ", " + b + ')'); return true; } public static void bar(String[] a, String b) { if(a != null) { for(int i=0; i < a.length; i++) { String s=a[i]; System.out.print(s + ' '); } } else System.out.println("a=null"); if(b != null) System.out.println("b=" + b); else System.out.println("b=null"); } public static void foobar() { System.out.println("foobar()"); } } @Test(enabled=false) public static void call(boolean b, Boolean bool, int i, double d, float f, byte[] buf, String[] strings) { System.out.println("b = " + b + ", bool=" + bool + ", i=" + i + ", d=" + d + ", f=" + f + ", buf=" + buf.length + " bytes, strings=" + Arrays.toString(strings)); } final TargetClass target=new TargetClass(); public void testMethod() throws Exception { Method m=TargetClass.class.getMethod("foo", int.class, String.class); MethodCall mc=new MethodCall(m,22, "Bela"); Assert.assertEquals(mc.invoke(target),Boolean.TRUE); } public void testMethod2() throws Exception { MethodCall call=new MethodCall(CALL, true, Boolean.FALSE, 322649, 3.24, (float)54.345, new byte[]{'b', 'e', 'l', 'a'}, new String[]{"Bela", "Michelle"}); call.invoke(this); } public void testTypes() throws Exception { MethodCall mc=new MethodCall("foo", new Object[]{35,"Bela"}, new Class[]{int.class,String.class}); Assert.assertEquals(mc.invoke(target),Boolean.TRUE); } public void testTypes2() throws Exception { new MethodCall("bar", new Object[]{new String[]{"one", "two", "three"}, "Bela"}, new Class[]{String[].class, String.class}).invoke(target); } public void testTypesWithArray() throws Exception { new MethodCall("bar", new Object[]{new String[]{"one", "two", "three"}, "Bela"}, new Class[]{String[].class, String.class}).invoke(target); } public void testTypesWithNullArgument() throws Exception { new MethodCall("bar", new Object[]{new String[]{"one", "two", "three"}, null}, new Class[]{String[].class, String.class}).invoke(target); } public void testTypesWithNullArgument2() throws Exception { MethodCall mc=new MethodCall("bar", new Object[]{new String[]{"one", "two", "three"}, new Object[]{}}, new Class[]{String[].class, String.class}); try { mc.invoke(target); assert false: "we should not get here as there should be an argument mismatch exception"; } catch(IllegalArgumentException ex) { System.out.println("caught IllegalArgumentException - as expected"); } } public void testTypesWithNullArgument3() throws Exception { new MethodCall("foobar", new Object[]{}, new Class[]{}).invoke(target); } public void testTypesWithNullArgument4() throws Exception { new MethodCall("foobar", null, null).invoke(target); } public void testTypesWithNullArgument5() throws Exception { new MethodCall("foobar", new Object[0], new Class[0]).invoke(target); } public void testSignature() throws Exception { MethodCall mc=new MethodCall("foo", new Object[]{35, "Bela"}, new Class[]{int.class, String.class}); Assert.assertEquals(mc.invoke(target),Boolean.TRUE); } public static void testBufferSize() throws Exception { MethodCall m=new MethodCall("foo", new Object[]{10,"Bela"}, new Class[]{int.class, String.class}); byte[] data=Util.objectToByteBuffer(m); MethodCall m2=Util.objectFromByteBuffer(data); System.out.println(m2); Object[] args=m2.args(); assert args.length == 2; assert args[0].equals(10); assert args[1].equals("Bela"); } public static void testOLD() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] {"abc"}, new Class[]{String.class}); Target target = new Target(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testInheritanceOLD() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] {"abc"}, new Class[]{String.class}); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testMETHOD() throws Exception { Method method = Target.class.getMethod("someMethod", String.class); MethodCall methodCall = new MethodCall(method, "abc"); Target target = new Target(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testInheritanceMETHOD() throws Exception { Method method = Target.class.getMethod("someMethod", String.class); MethodCall methodCall = new MethodCall(method, "abc"); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testTYPES() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] { "abc" }, new Class[] { String.class }); Target target = new Target(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testInheritanceTYPES() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] { "abc" }, new Class[] { String.class }); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } /** * This tests whether overriden methods are correctly identified and invoked. */ public static void testOverriddenForTYPES() throws Exception { MethodCall methodCall = new MethodCall("overriddenMethod", new Object[] { "abc" }, new Class[] { String.class }); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("TargetSubclassABC", result); } public static void testNoArgumentMethodForTYPES() throws Exception { MethodCall methodCall = new MethodCall("noArgumentMethod", new Object[0], new Class[0]); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("noArgumentMethodResult", result); } public static void testSIGNATURE() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] { "abc" }, new Class[] {String.class}); Target target = new Target(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testInheritanceSIGNATURE() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] {"abc"}, new Class[] {String.class}); TargetSubclass target = new TargetSubclass(); Object result = methodCall.invoke(target); Assert.assertEquals("ABC",result); } public static void testMarshalling() throws Exception { MethodCall methodCall = new MethodCall("someMethod", new Object[] { "abc" }, new Class[] {String.class}); System.out.println("methodCall: " + methodCall); MethodCall m=marshalAndUnmarshal(methodCall); System.out.println("m: " + m); } public static void testMarshalling2() throws Exception { Address addr=Util.createRandomAddress("A"); MethodCall call=new MethodCall("foo", new Object[]{"hello", 23, addr}, new Class[]{String.class, int.class, Address.class}); MethodCall m=marshalAndUnmarshal(call); System.out.println("m = " + m); } public static void testMarshallingMETHOD() throws Exception { Method m=TargetClass.class.getMethod("foo", int.class, String.class); MethodCall mc=new MethodCall(m,22, "Bela"); MethodCall call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); mc=new MethodCall(CALL, true, Boolean.FALSE, 322649, 3.24, (float)54.345, new byte[]{'b', 'e', 'l', 'a'}, new String[]{"Bela", "Michelle"}); call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); } public static void testMarshallingTYPES() throws Exception { MethodCall mc=new MethodCall("call", new Object[] {true,Boolean.FALSE,322649,3.24,(float)54.345, new byte[]{'b','e','l','a'},new String[]{"Bela","Michelle"}}, new Class<?>[]{boolean.class, Boolean.class, int.class, double.class, float.class, byte[].class, String[].class}); MethodCall call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); } public void testMarshallingID() throws Exception { MethodCall mc=new MethodCall((short)1, true, Boolean.FALSE, 322649, 3.24, (float)54.345, new byte[]{'b', 'e', 'l', 'a'}, new String[]{"Bela", "Michelle"}); MethodCall call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); mc=new MethodCall((short)1, true, Boolean.FALSE, 322649, 3.24, (float)54.345, new byte[]{'b', 'e', 'l', 'a'}, new String[]{"Bela", "Michelle"}); call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); mc=new MethodCall((short)2); call2=marshalAndUnmarshal(mc); System.out.println("call2 = " + call2); } private static MethodCall marshalAndUnmarshal(MethodCall m) throws Exception { byte[] buf=Util.objectToByteBuffer(m); System.out.println("marshalled buffer size: " + buf.length + " bytes"); return (MethodCall)Util.objectFromByteBuffer(buf); } public static class Target { public static String someMethod(String arg) { return arg.toUpperCase(); } public String overriddenMethod(String arg) { return "Target" + arg.toUpperCase(); } public static String noArgumentMethod() { return "noArgumentMethodResult"; } } public static class TargetSubclass extends Target { public String overriddenMethod(String arg) { return "TargetSubclass" + arg.toUpperCase(); } } }