diff --git a/common/src/main/java/org/red5/server/service/ReflectionUtils.java b/common/src/main/java/org/red5/server/service/ReflectionUtils.java index 29f6e093071b83261ae44ea74f6321f63cc41b60..0e71daad60cde105273c41e09eba15607e7924bb 100644 --- a/common/src/main/java/org/red5/server/service/ReflectionUtils.java +++ b/common/src/main/java/org/red5/server/service/ReflectionUtils.java @@ -136,15 +136,17 @@ public class ReflectionUtils { log.trace("Args / parameters count: {}", numParams); } // convert the args first - Object[] params = ConversionUtils.convertParams(args); + Class<?>[] params = ConversionUtils.convertParams(args); + if (params[0] != null && IConnection.class.isInstance(params[0])) { + // if it does implement IConnection use the interface + params[0] = IConnection.class; + } if (isDebug) { - for (Object clazz : params) { - log.debug("Parameter: {}", clazz); - } + Arrays.asList(params).forEach(param -> log.debug("Parameter: {}", param)); } // try to skip the listing of all the methods by checking for exactly what we want first try { - Method method = service.getClass().getMethod(methodName, (Class<?>[]) params); + Method method = service.getClass().getMethod(methodName, params); if (isDebug) { log.debug("Exact method found, skipping list: {}", methodName); } @@ -208,29 +210,29 @@ public class ReflectionUtils { public static Object[] findMethodWithListParameters(Object service, String methodName, Object[] args) { Method method = null; try { - //try to skip the listing of all the methods by checking for exactly what - //we want first - method = service.getClass().getMethod(methodName, ConversionUtils.convertParams(args)); + // convert the args first + Class<?>[] params = ConversionUtils.convertParams(args); + if (params[0] != null && IConnection.class.isInstance(params[0])) { + // if it does implement IConnection use the interface + params[0] = IConnection.class; + } + // try to skip the listing of all the methods by checking for exactly what we want first + method = service.getClass().getMethod(methodName, params); log.debug("Exact method found (skipping list): {}", methodName); return new Object[] { method, args }; } catch (NoSuchMethodException nsme) { log.debug("Method not found using exact parameter types", nsme); } - List<Method> methods = findMethodsByNameAndNumParams(service, methodName, 1); + List<Method> methods = findMethodsByNameAndNumParams(service, methodName, args.length); if (isTrace) { log.trace("Found {} methods", methods.size()); } if (!methods.isEmpty()) { log.debug("Multiple methods found with same name and parameter count; parameter conversion will be attempted in order"); - Object[] params = null; for (int i = 0; i < methods.size(); i++) { try { method = methods.get(i); - params = ConversionUtils.convertParams(args, method.getParameterTypes()); - if (args.length > 0 && (args[0] instanceof IConnection) && (!(params[0] instanceof IConnection))) { - // Don't convert first IConnection parameter - continue; - } + Object[] params = ConversionUtils.convertParams(args, method.getParameterTypes()); return new Object[] { method, params }; } catch (Exception ex) { log.debug("Parameter conversion failed", ex); diff --git a/io/src/main/java/org/red5/io/utils/ConversionUtils.java b/io/src/main/java/org/red5/io/utils/ConversionUtils.java index 1e7e6ee81217c61251b026b8269bf3daf02e96dc..cec9178f8f0e427af2511a932921327f303db40d 100644 --- a/io/src/main/java/org/red5/io/utils/ConversionUtils.java +++ b/io/src/main/java/org/red5/io/utils/ConversionUtils.java @@ -312,24 +312,16 @@ public class ConversionUtils { * @return Array of converted objects */ public static Class<?>[] convertParams(Object[] source) { - Class<?>[] converted = null; + Class<?>[] converted = new Class<?>[0]; if (source != null) { converted = new Class<?>[source.length]; for (int i = 0; i < source.length; i++) { if (source[i] != null) { - // if the class is not an instance of IConnection use its class - //if (!IConnection.class.isInstance(source[i])) { converted[i] = source[i].getClass(); - //} else { - // if it does implement IConnection use the interface - //converted[i] = IConnection.class; - //} } else { converted[i] = null; } } - } else { - converted = new Class<?>[0]; } if (log.isTraceEnabled()) { log.trace("Converted parameters: {}", Arrays.toString(converted)); diff --git a/server/src/test/java/org/red5/server/service/ReflectionUtilsTest.java b/server/src/test/java/org/red5/server/service/ReflectionUtilsTest.java index dce0a14020d440ed3e974617b1fc874340583e5c..cde8f841c8cf9ac4a2f638772ab557bbaf4164d2 100644 --- a/server/src/test/java/org/red5/server/service/ReflectionUtilsTest.java +++ b/server/src/test/java/org/red5/server/service/ReflectionUtilsTest.java @@ -32,7 +32,7 @@ public class ReflectionUtilsTest { log.info("Result: {}", Arrays.asList(result)); } assertNotEquals(NULL_RETURN, result); - // + // call with two parameters string and int call = new PendingCall("TestService.doTest", new Object[] { "test", 42 }); result = ReflectionUtils.findMethod(conn, call, service, methodName); if (result == null) { @@ -42,6 +42,19 @@ public class ReflectionUtilsTest { log.info("Result 2: {}", Arrays.asList(result)); } assertNotEquals(NULL_RETURN, result); + // call with two parameters string and int but expecting Connection as first parameter to hit on 2nd call + methodName = "doTestWithConn"; + call = new PendingCall("TestService.doTestWithConn", new Object[] { "test", 42 }); + result = ReflectionUtils.findMethod(conn, call, service, methodName); + if (result == null) { + log.info("Result is null"); + fail("Result is null, method not found"); + } else { + log.info("Result 2: {}", Arrays.asList(result)); + } + assertNotEquals(NULL_RETURN, result); + + } private class DummyConnection extends RTMPMinaConnection { @@ -54,9 +67,8 @@ public class ReflectionUtilsTest { log.info("doTest: {}", param); } - // method with IConnection as first parameter isn't found - public void doTest(IConnection conn, String param) { - log.info("doTest: {} {}", conn, param); + public void doTestWithConn(IConnection conn, String param0, Integer param1) { + log.info("doTestWithConn: {} {} {}", conn, param0, param1); } public void doTest(String param0, Integer param1) {