dubbo 2.5.3 bug 同名方法同参数个数重载ClassCastException
这次遇到的问题是com.alibaba.dubbo.rpc.protocol.dubbo.telnet.InvokeTelnetHandler.findMethod中一个bug
遍历所有方法时,首次匹配到方法名m.getName()和入参方法名method一致,且参数个数 m.getParameterTypes().length 同入参args.size()相同的方法,将invokeMethod设置为此方法,然后继续遍历方法列表。当即 invokeMethod != null 后,再次发现方法名m.getName()和参数方法名method一致,且参数个数 m.getParameterTypes().length 同入参args.size()相同的方法时,应该判断当前方法的参数m.getParameterTypes()和args是否匹配,而不是invokeMethod.getParameterTypes()和args是否匹配.
private static Method findMethod(Exporter<?> exporter, String method, List<Object> args) { Invoker<?> invoker = exporter.getInvoker(); Method[] methods = invoker.getInterface().getMethods(); Method invokeMethod = null; for (Method m : methods) { if (m.getName().equals(method) && m.getParameterTypes().length == args.size()) { if (invokeMethod != null) { // 重载 if (isMatch(invokeMethod.getParameterTypes(), args)) { invokeMethod = m; break; } } else { invokeMethod = m; } invoker = exporter.getInvoker(); } } return invokeMethod; } private static boolean isMatch(Class<?>[] types, List<Object> args) { if (types.length != args.size()) { return false; } for (int i = 0; i < types.length; i ++) { Class<?> type = types[i]; Object arg = args.get(i); if (ReflectUtils.isPrimitive(arg.getClass())) { if (! ReflectUtils.isPrimitive(type)) { return false; } } else if (arg instanceof Map) { String name = (String) ((Map<?, ?>)arg).get("class"); Class<?> cls = arg.getClass(); if (name != null && name.length() > 0) { cls = ReflectUtils.forName(name); } if (! type.isAssignableFrom(cls)) { return false; } } else if (arg instanceof Collection) { if (! type.isArray() && ! type.isAssignableFrom(arg.getClass())) { return false; } } else { if (! type.isAssignableFrom(arg.getClass())) { return false; } } } return true; }