core/play/src/main/java/play/libs/reflect/MethodUtils.java
public static Method getMatchingAccessibleMethod(
      final Class<?> cls, final String methodName, final Class<?>... parameterTypes) {
    try {
      final Method method = cls.getMethod(methodName, parameterTypes);
      MemberUtils.setAccessibleWorkaround(method);
      return method;
    } catch (final NoSuchMethodException e) { // NOPMD - Swallow the exception
    }
    // search through all methods
    Method bestMatch = null;
    final Method[] methods = cls.getMethods();
    for (final Method method : methods) {
      // compare name and parameters
      if (method.getName().equals(methodName)
          && MemberUtils.isMatchingMethod(method, parameterTypes)) {
        // get accessible version of method
        final Method accessibleMethod = getAccessibleMethod(method);
        if (accessibleMethod != null
            && (bestMatch == null
                || MemberUtils.compareMethodFit(accessibleMethod, bestMatch, parameterTypes) < 0)) {
          bestMatch = accessibleMethod;
        }
      }
    }
    if (bestMatch != null) {
      MemberUtils.setAccessibleWorkaround(bestMatch);
    }

    if (bestMatch != null
        && bestMatch.isVarArgs()
        && bestMatch.getParameterTypes().length > 0
        && parameterTypes.length > 0) {
      final Class<?>[] methodParameterTypes = bestMatch.getParameterTypes();
      final Class<?> methodParameterComponentType =
          methodParameterTypes[methodParameterTypes.length - 1].getComponentType();
      final String methodParameterComponentTypeName =
          ClassUtils.primitiveToWrapper(methodParameterComponentType).getName();
      final String parameterTypeName = parameterTypes[parameterTypes.length - 1].getName();
      final String parameterTypeSuperClassName =
          parameterTypes[parameterTypes.length - 1].getSuperclass().getName();

      if (!methodParameterComponentTypeName.equals(parameterTypeName)
          && !methodParameterComponentTypeName.equals(parameterTypeSuperClassName)) {
        return null;
      }
    }

    return bestMatch;
  }
public static Method getMatchingAccessibleMethod(
      final Class<?> cls, final String methodName, final Class<?>... parameterTypes) {
    try {
      final Method method = cls.getMethod(methodName, parameterTypes);
      MemberUtils.setAccessibleWorkaround(method);
      return method;
    } catch (final NoSuchMethodException e) { // NOPMD - Swallow the exception
    }
    // search through all methods
    Method bestMatch = null;
    final Method[] methods = cls.getMethods();
    for (final Method method : methods) {
      // compare name and parameters
      if (method.getName().equals(methodName)
          && MemberUtils.isMatchingMethod(method, parameterTypes)) {
        // get accessible version of method
        final Method accessibleMethod = getAccessibleMethod(method);
        if (accessibleMethod != null
            && (bestMatch == null
                || MemberUtils.compareMethodFit(accessibleMethod, bestMatch, parameterTypes) < 0)) {
          bestMatch = accessibleMethod;
        }
      }
    }
    if (bestMatch != null) {
      MemberUtils.setAccessibleWorkaround(bestMatch);
    }

    if (bestMatch != null
        && bestMatch.isVarArgs()
        && bestMatch.getParameterTypes().length > 0
        && parameterTypes.length > 0) {
      final Class<?>[] methodParameterTypes = bestMatch.getParameterTypes();
      final Class<?> methodParameterComponentType =
          methodParameterTypes[methodParameterTypes.length - 1].getComponentType();
      final String methodParameterComponentTypeName =
          ClassUtils.primitiveToWrapper(methodParameterComponentType).getName();
      final String parameterTypeName = parameterTypes[parameterTypes.length - 1].getName();
      final String parameterTypeSuperClassName =
          parameterTypes[parameterTypes.length - 1].getSuperclass().getName();

      if (!methodParameterComponentTypeName.equals(parameterTypeName)
          && !methodParameterComponentTypeName.equals(parameterTypeSuperClassName)) {
        return null;
      }
    }

    return bestMatch;
  }
Finds an accessible method that matches the given name and has compatible parameters.
Compatible parameters mean that every method parameter is assignable from the given parameters.
In other words, it finds a method with the given name that will take the parameters given.

<p>This method can match primitive parameter by passing in wrapper classes. For example, a
{@code Boolean} will match a primitive {@code boolean} parameter.

@param cls find method in this class
@param methodName find method with this name
@param parameterTypes find method with most compatible parameters
@return The accessible method