Spec-Zone .ru
спецификации, руководства, описания, API
|
CONTENTS | PREV | NEXT | Java Remote Method Invocation |
When the RMI runtime implementation needs instances ofjava.net.Socket
andjava.net.ServerSocket
for its connections, instead of instantiating objects of those classes directly, it calls thecreateSocket
andcreateServerSocket
methods on the currentRMISocketFactory
object, returned by the static methodRMISocketFactory.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 thejava.net.Socket
andjava.net.ServerSocket
classes. The instance ofRMISocketFactory
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 werehost
andport
(forcreateSocket
) and justport
(forcreateServerSocket
).In the Java 2 platform, the new interfaces
RMIServerSocketFactory
andRMIClientSocketFactory
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 bothUnicastRemoteObject
andjava.rmi.activation.Activatable.
Remote objects exported with either of the new constructors or
exportObject
methods (withRMIClientSocketFactory
andRMIServerSocketFactory
parameters) will be treated differently by the RMI runtime. For the lifetime of such a remote object, the runtime will use the customRMIServerSocketFactory
to create aServerSocket
to accept incoming calls to the remote object and use the customRMIClientSocketFactory
to create aSocket
to connect clients to the remote object.The implementation of
RemoteRef
andServerRef
used in the stubs and skeletons for remote objects exported with custom socket factories isUnicastRef2
andUnicastServerRef2
, respectively. The wire representation of theUnicastRef2
type contains a different representation of the "endpoint" to contact than theUnicastRef
type has (which used just a host name string in UTF format, following by an integer port number). ForUnicastRef2
, 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 anRMIClientSocketFactory
object that is used by clients to generate socket connections to remote object at this endpoint. The endpoint representation does not contain theRMIServerSocketFactory
object that was specified when the remote object was exported.When calls are made through references of the
UnicastRef2
type, the runtime uses thecreateSocket
method of theRMIClientSocketFactory
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 sameRMIClientSocketFactory
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 haveRemoteRef
andServerRef
of typeUnicastRef
andUnicastServerRef
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
Class
Thejava.rmi.server.RMISocketFactory
abstract class provides an interface for specifying how the transport should obtain sockets. Note that the class below usesSocket
andServerSocket
from thejava.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 methodsetSocketFactory
is used to set the socket factory from which RMI obtains sockets. The application may invoke this method with its ownRMISocketFactory
instance only once. An application-defined implementation ofRMISocketFactory
could, for example, do preliminary filtering on the requested connection and throw exceptions, or return its own extension of thejava.net.Socket
orjava.net.ServerSocket
classes, such as ones that provide a secure communication channel. Note that theRMISocketFactory
may only be set if the current security manager allows setting a socket factory; if setting the socket factory is disallowed, aSecurityException
will be thrown.The static method
getSocketFactory
returns the socket factory used by RMI. The method returnsnull
if the socket factory is not set.The transport layer invokes the
createSocket
andcreateServerSocket
methods on theRMISocketFactory
returned by thegetSocketFactory
method when the transport needs to create sockets. For example:
RMISocketFactory.getSocketFactory().createSocket(myhost, myport)
The methodcreateSocket
should create a client socket connected to the specified host and port. The methodcreateServerSocket
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:
- On
createSocket
, the factory automatically attempts HTTP connections to hosts that cannot be contacted with a direct socket.- On
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.
The methodsetFailureHandler
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 returnsfalse
, meaning that by default recreation of sockets is not attempted by the runtime.The method
getFailureHandler
returns the current handler for socket creation failure, ornull
if the failure handler is not set.
RMIServerSocketFactory
Interface
To support custom communication with remote objects, anRMIServerSocketFactory
instance can be specified for a remote object when it is exported, either via the appropriateUnicastRemoteObject
constructor orexportObject
method or the appropriatejava.rmi.activation.Activatable
constructor orexportObject
method. If such a server socket factory is associated with a remote object when it is exported, the RMI runtime will use the remote object's server socket factory to create aServerSocket
(using theRMIServerSocketFactory.createServerSocket
method) to accept connections from remote clients.
package java.rmi.server;public interface RMIServerSocketFactory { public java.net.ServerSocket createServerSocket(int port) throws IOException; }
RMIClientSocketFactory
Interface
For custom communication with remote objects, anRMIClientSocketFactory
instance can be specified for a remote object when it is exported, either via the appropriateUnicastRemoteObject
constructor orexportObject
method or the appropriatejava.rmi.activation.Activatable
constructor orexportObject
method. If such a client socket factory is associated with a remote object when it is exported, the client socket factory will be downloaded to remote virtual machines along with the remote reference for the remote object and the RMI runtime will use theRMIClientSocketFactory.createSocket
method to make connections from the client to the remote object .
package java.rmi.server;public interface RMIClientSocketFactory { public java.net.Socket createSocket(String host, int port) throws IOException; }