{
if(this.server == null)
{
log.debug("Server stub has not been set in RMI invoker client. See previous errors for details.");
//throw new IOException("Server stub hasn't been set!");
throw new CannotConnectException("Server stub has not been set.");
}
try
{
Object payload = invocation;
if(marshaller != null && !(marshaller instanceof RMIMarshaller))
{
if(marshaller instanceof MarshallerDecorator)
{
payload = ((MarshallerDecorator) marshaller).addDecoration(payload);
}
else
{
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
if (marshaller instanceof VersionedMarshaller)
((VersionedMarshaller) marshaller).write(payload, byteOut, getVersion());
else
marshaller.write(payload, byteOut);
byteOut.close();
if (rmiOnewayMarshalling)
{
// Legacy treatment, pre 2.4.0.
ByteArrayInputStream bais = new ByteArrayInputStream(byteOut.toByteArray());
SerializationManager manager = SerializationStreamFactory.getManagerInstance(getSerializationType());
ObjectInputStream ois = manager.createInput(bais, getClassLoader());
try
{
byteOut.close();
payload = ois.readObject();
ois.close();
}
catch(ClassNotFoundException e)
{
log.debug("Could not marshall invocation payload object " + payload, e);
throw new IOException(e.getMessage());
}
}
else
{
payload = byteOut.toByteArray();
}
}
}
int simulatedTimeout = getSimulatedTimeout(configuration, metadata);
if (simulatedTimeout <= 0)
{
Object result = server.transport(payload);
return unmarshal(result, unmarshaller, metadata);
}
else
{
if (log.isTraceEnabled()) log.trace("using simulated timeout: " + simulatedTimeout);
class Holder {public Object value;}
final Holder resultHolder = new Holder();
final Object finalPayload = payload;
Runnable r = new Runnable()
{
public void run()
{
try
{
resultHolder.value = server.transport(finalPayload);
if (log.isTraceEnabled()) log.trace("result: " + resultHolder.value);
}
catch (Exception e)
{
resultHolder.value = e;
if (log.isTraceEnabled()) log.trace("exception: " + e);
}
}
};
// BasicThreadPool timeout mechanism depends on the interrupted status of
// the running thread.
Thread.interrupted();
ThreadPool pool = getTimeoutThreadPool();
WaitingTaskWrapper wrapper = new WaitingTaskWrapper(r, simulatedTimeout);
if (log.isTraceEnabled()) log.trace("starting task in thread pool");
pool.runTaskWrapper(wrapper);
if (log.isTraceEnabled()) log.trace("task finished in thread pool");
Object result = unmarshal(resultHolder.value, unmarshaller, metadata);
if (result == null)
{
if (log.isTraceEnabled()) log.trace("invocation timed out");
Exception cause = new SocketTimeoutException("timed out");
throw new CannotConnectException("Can not connect http client invoker.", cause);
}
else if (result instanceof IOException)
{
throw (IOException) result;
}
else if (result instanceof RuntimeException)
{
throw (RuntimeException) result;
}
else
{
if (log.isTraceEnabled()) log.trace("returning result: " + result);
return result;
}
}
}
catch(RemoteException e)
{
log.debug("Error making invocation in RMI client invoker.", e);
throw new CannotConnectException("Error making invocation in RMI client invoker.", e);
}
}