public int getTypeDifferenceWeight(Class<?>[] paramTypes) {
   // If valid arguments found, determine type difference weight.
   // Try type difference weight on both the converted arguments and
   // the raw arguments. If the raw weight is better, use it.
   // Decrease raw weight by 1024 to prefer it over equal converted weight.
   int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
   int rawTypeDiffWeight =
       MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
   return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
 }
    /** Invoke the method via the MethodInvoker. */
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
      MethodInvoker methodInvoker = new MethodInvoker();

      try {
        methodInvoker.setTargetObject(getBean(context, beanName));
        methodInvoker.setTargetMethod(executionMethod);

        methodInvoker.prepare();

        context.setResult(methodInvoker.invoke());
      } catch (InvocationTargetException ex) {
        if (ex.getTargetException() instanceof JobExecutionException) {
          throw (JobExecutionException) ex.getTargetException();
        } else {
          throw new JobMethodInvocationFailedException(methodInvoker, ex.getTargetException());
        }
      } catch (JobExecutionException ex) {
        throw ex;
      } catch (Exception ex) {
        throw new JobExecutionException(ex);
      }
    }
  /** {@inheritDoc} */
  @Override
  public Object execute(String method, @SuppressWarnings("rawtypes") Vector params)
      throws Exception {

    LOG.debug("calling: {}({})", method, toArgList(params));

    MethodInvoker invoker = new ArgumentConvertingMethodInvoker();
    invoker.setTargetObject(this.proxy);
    invoker.setTargetMethod(getMethodName(method));
    invoker.setArguments(params.toArray());
    invoker.prepare();

    try {
      Object returnValue = invoker.invoke();

      if (returnValue == null && invoker.getPreparedMethod().getReturnType() == Void.TYPE) {
        returnValue = "void";
      } else if (returnValue instanceof Map<?, ?> && !(returnValue instanceof Hashtable<?, ?>)) {
        returnValue = new Hashtable<Object, Object>((Map<?, ?>) returnValue);
      } else if (returnValue instanceof Collection<?> && !(returnValue instanceof Vector<?>)) {
        returnValue = new Vector<Object>((Collection<?>) returnValue);
      }

      LOG.debug("returning from: {}({}) result = {}", method, toArgList(params), returnValue);
      return returnValue;

    } catch (InvocationTargetException e) {
      Throwable targetException = e.getTargetException();
      if (targetException instanceof IllegalArgumentException) {
        throw new MsgPreservingXmlRpcException(
            XmlRpcConstants.FAULT_INVALID_DATA, targetException.getMessage());
      } else if (targetException instanceof MalformedURLException) {
        throw new MsgPreservingXmlRpcException(
            XmlRpcConstants.FAULT_INVALID_URL, targetException.getMessage());
      } else if (targetException instanceof Exception && targetException.toString() != null) {
        throw (Exception) targetException;
      }

      String msg = targetException.toString();
      if (msg == null) msg = targetException.getClass().getName();

      Exception ex = new Exception(msg, targetException);
      ex.setStackTrace(targetException.getStackTrace());
      throw ex;
    }
  }