use of sun.rmi.transport.Connection in project jdk8u_jdk by JetBrains.
the class UnicastRef method invoke.
/**
* Invoke a method. This form of delegating method invocation
* to the reference allows the reference to take care of
* setting up the connection to the remote host, marshalling
* some representation for the method and parameters, then
* communicating the method invocation to the remote host.
* This method either returns the result of a method invocation
* on the remote object which resides on the remote host or
* throws a RemoteException if the call failed or an
* application-level exception if the remote invocation throws
* an exception.
*
* @param obj the proxy for the remote object
* @param method the method to be invoked
* @param params the parameter list
* @param opnum a hash that may be used to represent the method
* @since 1.2
*/
public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
if (clientRefLog.isLoggable(Log.VERBOSE)) {
clientRefLog.log(Log.VERBOSE, "method: " + method);
}
if (clientCallLog.isLoggable(Log.VERBOSE)) {
logClientCall(obj, method);
}
Connection conn = ref.getChannel().newConnection();
RemoteCall call = null;
boolean reuse = true;
/* If the call connection is "reused" early, remember not to
* reuse again.
*/
boolean alreadyFreed = false;
try {
if (clientRefLog.isLoggable(Log.VERBOSE)) {
clientRefLog.log(Log.VERBOSE, "opnum = " + opnum);
}
// create call context
call = new StreamRemoteCall(conn, ref.getObjID(), -1, opnum);
// marshal parameters
try {
ObjectOutput out = call.getOutputStream();
marshalCustomCallData(out);
Class<?>[] types = method.getParameterTypes();
for (int i = 0; i < types.length; i++) {
marshalValue(types[i], params[i], out);
}
} catch (IOException e) {
clientRefLog.log(Log.BRIEF, "IOException marshalling arguments: ", e);
throw new MarshalException("error marshalling arguments", e);
}
// unmarshal return
call.executeCall();
try {
Class<?> rtype = method.getReturnType();
if (rtype == void.class)
return null;
ObjectInput in = call.getInputStream();
/* StreamRemoteCall.done() does not actually make use
* of conn, therefore it is safe to reuse this
* connection before the dirty call is sent for
* registered refs.
*/
Object returnValue = unmarshalValue(rtype, in);
/* we are freeing the connection now, do not free
* again or reuse.
*/
alreadyFreed = true;
/* if we got to this point, reuse must have been true. */
clientRefLog.log(Log.BRIEF, "free connection (reuse = true)");
/* Free the call's connection early. */
ref.getChannel().free(conn, true);
return returnValue;
} catch (IOException e) {
clientRefLog.log(Log.BRIEF, "IOException unmarshalling return: ", e);
throw new UnmarshalException("error unmarshalling return", e);
} catch (ClassNotFoundException e) {
clientRefLog.log(Log.BRIEF, "ClassNotFoundException unmarshalling return: ", e);
throw new UnmarshalException("error unmarshalling return", e);
} finally {
try {
call.done();
} catch (IOException e) {
/* WARNING: If the conn has been reused early,
* then it is too late to recover from thrown
* IOExceptions caught here. This code is relying
* on StreamRemoteCall.done() not actually
* throwing IOExceptions.
*/
reuse = false;
}
}
} catch (RuntimeException e) {
/*
* Need to distinguish between client (generated by the
* invoke method itself) and server RuntimeExceptions.
* Client side RuntimeExceptions are likely to have
* corrupted the call connection and those from the server
* are not likely to have done so. If the exception came
* from the server the call connection should be reused.
*/
if ((call == null) || (((StreamRemoteCall) call).getServerException() != e)) {
reuse = false;
}
throw e;
} catch (RemoteException e) {
/*
* Some failure during call; assume connection cannot
* be reused. Must assume failure even if ServerException
* or ServerError occurs since these failures can happen
* during parameter deserialization which would leave
* the connection in a corrupted state.
*/
reuse = false;
throw e;
} catch (Error e) {
/* If errors occurred, the connection is most likely not
* reusable.
*/
reuse = false;
throw e;
} finally {
/* alreadyFreed ensures that we do not log a reuse that
* may have already happened.
*/
if (!alreadyFreed) {
if (clientRefLog.isLoggable(Log.BRIEF)) {
clientRefLog.log(Log.BRIEF, "free connection (reuse = " + reuse + ")");
}
ref.getChannel().free(conn, reuse);
}
}
}
use of sun.rmi.transport.Connection in project jdk8u_jdk by JetBrains.
the class UnicastRef method free.
/**
* Private method to free a connection.
*/
private void free(RemoteCall call, boolean reuse) throws RemoteException {
Connection conn = ((StreamRemoteCall) call).getConnection();
ref.getChannel().free(conn, reuse);
}
use of sun.rmi.transport.Connection in project jdk8u_jdk by JetBrains.
the class ConnectionAcceptor method shedCache.
/**
* Closes all the connections in the cache, whether timed out or not.
*/
public void shedCache() {
// Build a list of connections, to avoid holding the freeList
// lock during (potentially long-running) close() calls.
Connection[] conn;
synchronized (freeList) {
conn = freeList.toArray(new Connection[freeList.size()]);
freeList.clear();
}
// Close all the connections that were free
for (int i = conn.length; --i >= 0; ) {
Connection c = conn[i];
// help gc
conn[i] = null;
try {
c.close();
} catch (java.io.IOException e) {
// eat exception
}
}
}
use of sun.rmi.transport.Connection in project jdk8u_jdk by JetBrains.
the class ConnectionAcceptor method createConnection.
/**
* Create a new connection to the remote endpoint of this channel.
* The returned connection is new. The caller must already have
* passed a security checkConnect or equivalent.
*/
private Connection createConnection() throws RemoteException {
Connection conn;
TCPTransport.tcpLog.log(Log.BRIEF, "create connection");
if (!usingMultiplexer) {
Socket sock = ep.newSocket();
conn = new TCPConnection(this, sock);
try {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
writeTransportHeader(out);
// choose protocol (single op if not reusable socket)
if (!conn.isReusable()) {
out.writeByte(TransportConstants.SingleOpProtocol);
} else {
out.writeByte(TransportConstants.StreamProtocol);
out.flush();
/*
* Set socket read timeout to configured value for JRMP
* connection handshake; this also serves to guard against
* non-JRMP servers that do not respond (see 4322806).
*/
int originalSoTimeout = 0;
try {
originalSoTimeout = sock.getSoTimeout();
sock.setSoTimeout(handshakeTimeout);
} catch (Exception e) {
// if we fail to set this, ignore and proceed anyway
}
DataInputStream in = new DataInputStream(conn.getInputStream());
byte ack = in.readByte();
if (ack != TransportConstants.ProtocolAck) {
throw new ConnectIOException(ack == TransportConstants.ProtocolNack ? "JRMP StreamProtocol not supported by server" : "non-JRMP server at remote endpoint");
}
String suggestedHost = in.readUTF();
int suggestedPort = in.readInt();
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "server suggested " + suggestedHost + ":" + suggestedPort);
}
// set local host name, if unknown
TCPEndpoint.setLocalHost(suggestedHost);
// do NOT set the default port, because we don't
// know if we can't listen YET...
// write out default endpoint to match protocol
// (but it serves no purpose)
TCPEndpoint localEp = TCPEndpoint.getLocalEndpoint(0, null, null);
out.writeUTF(localEp.getHost());
out.writeInt(localEp.getPort());
if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
TCPTransport.tcpLog.log(Log.VERBOSE, "using " + localEp.getHost() + ":" + localEp.getPort());
}
/*
* After JRMP handshake, set socket read timeout to value
* configured for the rest of the lifetime of the
* connection. NOTE: this timeout, if configured to a
* finite duration, places an upper bound on the time
* that a remote method call is permitted to execute.
*/
try {
/*
* If socket factory had set a non-zero timeout on its
* own, then restore it instead of using the property-
* configured value.
*/
sock.setSoTimeout((originalSoTimeout != 0 ? originalSoTimeout : responseTimeout));
} catch (Exception e) {
// if we fail to set this, ignore and proceed anyway
}
out.flush();
}
} catch (IOException e) {
if (e instanceof RemoteException)
throw (RemoteException) e;
else
throw new ConnectIOException("error during JRMP connection establishment", e);
}
} else {
try {
conn = multiplexer.openConnection();
} catch (IOException e) {
synchronized (this) {
usingMultiplexer = false;
multiplexer = null;
}
throw new ConnectIOException("error opening virtual connection " + "over multiplexed connection", e);
}
}
return conn;
}
use of sun.rmi.transport.Connection in project jdk8u_jdk by JetBrains.
the class ConnectionAcceptor method run.
/**
* Give transport next accepted connection, when available.
*/
public void run() {
Connection conn;
synchronized (queue) {
while (queue.size() == 0) {
try {
queue.wait();
} catch (InterruptedException e) {
}
}
startNewAcceptor();
conn = queue.remove(0);
}
transport.handleMessages(conn, true);
}
Aggregations