| CONTENTS | PREV | NEXT | Java Remote Method Invocation |
java.net.Socket and
java.net.ServerSocket for its connections, instead of
instantiating objects of those classes directly, it calls the
createSocket and createServerSocket
methods on the current RMISocketFactory object,
returned by the static method
RMISocketFactory.getSocketFactory. This allows the
application to have a hook to customize the type of sockets used by
the RMI transport, such as alternate subclasses of the
java.net.Socket and java.net.ServerSocket
classes. The instance of RMISocketFactory to be used
can be set once by trusted system code. In JDK1.1, this
customization was limited to relatively global decisions about
socket type, because the only parameters supplied to the factory's
methods were host and port (for
createSocket) and just port (for
createServerSocket).
In the Java SE platform, the new
interfaces RMIServerSocketFactory and
RMIClientSocketFactory have been introduced to provide
more flexible customization of what protocols are used to
communicate with remote objects.
To allow applications using RMI to
take advantage of these new socket factory interfaces, several new
constructors and exportObject methods, that take the
client and server socket factory as additional parameters, have
been added to both UnicastRemoteObject and
java.rmi.activation.Activatable.
Remote objects exported with either
of the new constructors or exportObject methods (with
RMIClientSocketFactory and
RMIServerSocketFactory parameters) will be treated
differently by the RMI runtime. For the lifetime of such a remote
object, the runtime will use the custom
RMIServerSocketFactory to create a
ServerSocket to accept incoming calls to the remote
object and use the custom RMIClientSocketFactory to
create a Socket to connect clients to the remote
object.
The implementation of
RemoteRef and ServerRef used in the stubs
and skeletons for remote objects exported with custom socket
factories is UnicastRef2 and
UnicastServerRef2, respectively. The wire
representation of the UnicastRef2 type contains a
different representation of the "endpoint" to contact than
the UnicastRef type has (which used just a host name
string in UTF format, following by an integer port number). For
UnicastRef2, the endpoint's wire representation
consists of a format byte specifying the contents of the rest of
the endpoint's representation (to allow for future expansion of the
endpoint representation) followed by data in the indicated format.
Currently, the data may consist of a hostname in UTF format, a port
number, and optionally (as specified by the endpoint format byte)
the serialized representation of an
RMIClientSocketFactory object that is used by clients
to generate socket connections to remote object at this endpoint.
The endpoint representation does not contain the
RMIServerSocketFactory object that was specified when
the remote object was exported.
When calls are made through
references of the UnicastRef2 type, the runtime uses
the createSocket method of the
RMIClientSocketFactory object in the endpoint when
creating sockets for connections to the referent remote object.
Also, when the runtime makes DGC "dirty" and
"clean" calls for a particular remote object, it must call
the DGC on the remote JVM using a connection generated from the
same RMIClientSocketFactory object as specified in the
remote reference, and the DGC implementation on the server side
should verify that this was done correctly.
Remote objects exported with the
older constructor or method on UnicastRemoteObject
that do not take custom socket factories as arguments will have
RemoteRef and ServerRef of type
UnicastRef and UnicastServerRef as before
and use the old wire representation for their endpoints, i.e. a
host string in UTF format followed by an integer specifying the
port number. This is so that RMI servers that do not use new 1.2
features will interoperate with older RMI clients.
RMISocketFactory Classjava.rmi.server.RMISocketFactory abstract class
provides an interface for specifying how the transport should
obtain sockets. Note that the class below uses Socket
and ServerSocket from the java.net
package.
package java.rmi.server;
public abstract class RMISocketFactory
implements RMIClientSocketFactory, RMIServerSocketFactory
{
public abstract Socket createSocket(String host, int port)
throws IOException;
public abstract ServerSocket createServerSocket(int port)
throws IOException;
public static void setSocketFactory(RMISocketFactory fac)
throws IOException {...}
public static RMISocketFactory getSocketFactory() {...}
public static void setFailureHandler(RMIFailureHandler fh) {...}
public static RMIFailureHandler getFailureHandler() {...}
}
The static method
setSocketFactory is used to set the socket factory
from which RMI obtains sockets. The application may invoke this
method with its own RMISocketFactory instance only
once. An application-defined implementation of
RMISocketFactory could, for example, do preliminary
filtering on the requested connection and throw exceptions, or
return its own extension of the java.net.Socket or
java.net.ServerSocket classes, such as ones that
provide a secure communication channel. Note that the
RMISocketFactory may only be set if the current
security manager allows setting a socket factory; if setting the
socket factory is disallowed, a SecurityException will
be thrown.
The static method
getSocketFactory returns the socket factory used by
RMI. The method returns null if the socket factory is
not set.
The transport layer invokes the
createSocket and createServerSocket
methods on the RMISocketFactory returned by the
getSocketFactory method when the transport needs to
create sockets. For example:
RMISocketFactory.getSocketFactory().createSocket(myhost, myport)
The method createSocket
should create a client socket connected to the specified
host and port. The method
createServerSocket should create a server socket on
the specified port.
The default transport's
implementation of RMISocketFactory provides for
transparent RMI through firewalls using HTTP as follows:
createSocket, the
factory automatically attempts HTTP connections to hosts that
cannot be contacted with a direct socket.createServerSocket,
the factory returns a server socket that automatically detects if a
newly accepted connection is an HTTP POST request. If so, it
returns a socket that will transparently expose only the body of
the request to the transport and format its output as an HTTP
response.setFailureHandler sets the failure handler to be
called by the RMI runtime if the creation of a server socket fails.
The failure handler returns a boolean to indicate if retry should
occur. The default failure handler returns false,
meaning that by default recreation of sockets is not attempted by
the runtime.
The method
getFailureHandler returns the current handler for
socket creation failure, or null if the failure
handler is not set.
RMIServerSocketFactory InterfaceRMIServerSocketFactory API documentation.
RMIClientSocketFactory InterfaceRMIClientSocketFactory API documentation.