private void handleClientMessage(ClientMessage clientMessage)
        throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
      int correlationId = clientMessage.getCorrelationId();

      final ClientInvocation future = deRegisterCallId(correlationId);
      if (future == null) {
        logger.warning("No call for callId: " + correlationId + ", response: " + clientMessage);
        return;
      }

      if (ErrorCodec.TYPE == clientMessage.getMessageType()) {
        ErrorCodec exParameters = ErrorCodec.decode(clientMessage);
        Throwable exception =
            clientExceptionFactory.createException(
                exParameters.errorCode,
                exParameters.className,
                exParameters.message,
                exParameters.stackTrace,
                exParameters.causeErrorCode,
                exParameters.causeClassName);
        future.notifyException(exception);
      } else {
        future.notify(clientMessage);
      }
    }
    private void handleClientMessage(ClientMessage clientMessage)
        throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
      int correlationId = clientMessage.getCorrelationId();

      final ClientInvocation future = deRegisterCallId(correlationId);
      if (future == null) {
        logger.warning("No call for callId: " + correlationId + ", response: " + clientMessage);
        return;
      }

      if (ExceptionResultParameters.TYPE == clientMessage.getMessageType()) {
        ExceptionResultParameters exceptionResultParameters =
            ExceptionResultParameters.decode(clientMessage);
        Throwable exception;
        if (exceptionResultParameters.causeClassName != null) {
          Class<?> causeClazz = Class.forName(exceptionResultParameters.causeClassName);
          Constructor<?> causeConstructor =
              causeClazz.getDeclaredConstructor(new Class[] {String.class});
          causeConstructor.setAccessible(true);
          Throwable cause =
              (Throwable) causeConstructor.newInstance(exceptionResultParameters.message);

          Class<?> clazz = Class.forName(exceptionResultParameters.className);
          Constructor<?> constructor =
              clazz.getDeclaredConstructor(new Class[] {String.class, Throwable.class});
          constructor.setAccessible(true);
          exception = (Throwable) constructor.newInstance(exceptionResultParameters.message, cause);
        } else {
          Class<?> clazz = Class.forName(exceptionResultParameters.className);
          Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[] {String.class});
          constructor.setAccessible(true);
          exception = (Throwable) constructor.newInstance(exceptionResultParameters.message);
        }
        future.notifyException(exception);
      } else {
        future.notify(clientMessage);
      }
    }