Permit permit = null;
Method pojo_method = null;
RemotePojoInvocationCommandResponse response;
ConcurrencyManager concurrency_manager = getServiceContainer().getConcurrencyManager();
try {
// look up the remote POJO that has the target interface
Object pojo = m_remotedPojos.get(target_interface_name);
if (pojo == null) {
throw new NoSuchMethodException(LOG.getMsgString(CommI18NResourceKeys.NO_POJO_SERVICE, command));
}
for (int x = 0; x < signature.length; x++) {
class_signature[x] = ClassUtil.getClassFromTypeName(signature[x]);
}
// If the remote POJO interface method has limited concurrency allowed, we need to make
// sure we have permission to invoke that method. None of these calls should throw an exception.
Class<?> target_interface = Class.forName(target_interface_name);
Method target_method = target_interface.getMethod(method_name, class_signature);
LimitedConcurrency limited_concurrency = target_method.getAnnotation(LimitedConcurrency.class);
if ((limited_concurrency != null) && (concurrency_manager != null)) {
permit = concurrency_manager.getPermit(limited_concurrency.value());
}
// if a parameter is a remote stream, we have to create a sender for it to use
// this is needed in case the remote server that is serving the stream data requires SSL - in that
// case, our sender needs to have SSL configured properly
for (int x = 0; x < signature.length; x++) // yes use signature, not param - avoids possible NPE
{
if (params[x] instanceof RemoteInputStream) {
prepareRemoteInputStream((RemoteInputStream) params[x]);
} else if (params[x] instanceof RemoteOutputStream) {
prepareRemoteOutputStream((RemoteOutputStream) params[x]);
}
}
// use reflection to make the call
pojo_method = pojo.getClass().getMethod(method_name, class_signature);
Object response_object = pojo_method.invoke(pojo, params);
response = new RemotePojoInvocationCommandResponse(remote_pojo_command, response_object);
} catch (InvocationTargetException e) {
// we want to make sure we keep the exception as intact as possible
// so we still want to put the invocation target exception in the response,
// but that is a java.* exception, so we need to drill down into the cause and wrap that if need be
Throwable response_exception;
if (e.getCause() != null) {
response_exception = new InvocationTargetException(getWrappedException(e.getCause(), pojo_method), e
.getMessage());
} else {
response_exception = getWrappedException(e, pojo_method);
}
response = new RemotePojoInvocationCommandResponse(remote_pojo_command, response_exception);
} catch (NotPermittedException npe) {
LOG.debug(CommI18NResourceKeys.COMMAND_NOT_PERMITTED, target_interface_name + '.' + method_name, npe
.getSleepBeforeRetry());
response = new RemotePojoInvocationCommandResponse(remote_pojo_command, npe);
} catch (Exception e) {
LOG.warn(e, CommI18NResourceKeys.REMOTE_POJO_EXECUTE_FAILURE);
response = new RemotePojoInvocationCommandResponse(remote_pojo_command, getWrappedException(e, pojo_method));
} finally {
if (concurrency_manager != null) {
concurrency_manager.releasePermit(permit);
}
}
return response;
}