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.