The RMI transport layer
normally attempts to open direct sockets to hosts on the Internet.
Many intranets, however, have firewalls that do not allow this. The
default RMI transport, therefore, provides two alternate HTTP-based
mechanisms which enable a client behind a firewall to invoke a
method on a remote object which resides outside the firewall.
As described in this
section, the HTTP-based mechanism that the RMI transport layer uses
for RMI calls only applies to firewalls with HTTP proxy
servers.
3.5.1 How an RMI Call is Packaged within the HTTP
Protocol
To get outside a firewall, the transport layer embeds an RMI call
within the firewall-trusted HTTP protocol. The RMI call data is
sent outside as the body of an HTTP POST request, and the return
information is sent back in the body of the HTTP response. The
transport layer will formulate the POST request in one of two ways:
- If the firewall proxy will forward an HTTP request directed to
an arbitrary port on the host machine, then it is forwarded
directly to the port on which the RMI server is listening. The
default RMI transport layer on the target machine is listening with
a server socket that is capable of understanding and decoding RMI
calls inside POST requests.
- If the firewall proxy will only forward HTTP requests directed
to certain well-known HTTP ports, then the call is forwarded to the
HTTP server listening on port 80 of the host machine, and a CGI
script is executed to forward the call to the target RMI server
port on the same machine.
3.5.2 The Default Socket Factory
The RMI transport implementation includes an extension of the class
java.rmi.server.RMISocketFactory, which is the default
resource-provider for client and server sockets used to send and
receive RMI calls; this default socket factory can be obtained via
the
java.rmi.server.RMISocketFactory.getDefaultSocketFactory
method. This default socket factory creates sockets that
transparently provide the firewall tunnelling mechanism as follows:
- Client sockets first attempt a direct socket connection. Client
sockets automatically attempt HTTP connections to hosts that cannot
be contacted with a direct socket if that direct socket connection
results in either a
java.net.NoRouteToHostException or
a java.net.UnknownHostException being thrown. If a
direct socket connection results in any other
java.io.IOException being thrown, such as a
java.net.ConnectException, the implementation may
attempt an HTTP connection.
- Server sockets automatically detect if a newly-accepted
connection is an HTTP POST request, and if so, return a socket that
will expose only the body of the request to the transport and
format its output as an HTTP response.
Client-side sockets, with this default behavior, are provided by
the factory's
java.rmi.server.RMISocketFactory.createSocket method.
Server-side sockets with this default behavior are provided by the
factory's
java.rmi.server.RMISocketFactory.createServerSocket
method.
3.5.3 Configuring the Client
A client can disable the packaging of RMI calls as HTTP requests by
setting the java.rmi.server.disableHttp property to
equal the boolean value true.
3.5.4 Configuring the Server
Note - The host name should
not be specified as the host's IP address, because some firewall
proxies will not forward to such a host name.
- In order for a client outside the server host's domain to be
able to invoke methods on a server's remote objects, the client
must be able to find the server. To do this, the remote references
that the server exports must contain the fully-qualified name of
the server host.
Depending on the server's platform and network environment, this
information may or may not be available to the Java virtual machine
on which the server is running. If it is not available, the host's
fully qualified name must be specified with the property
java.rmi.server.hostname when starting the server.
For example, use this command to start the RMI server class
ServerImpl on the machine chatsubo.example.com:
java -Djava.rmi.server.hostname=chatsubo.example.com ServerImpl
- If the server will not support RMI clients behind firewalls
that can forward to arbitrary ports, use this configuration:
- An HTTP server is listening on port 80.
- A suitable CGI endpoint is configured for HTTP-to-CGI
tunneling. This endpoint:
- Invokes the local interpreter for the Java programming language
to execute a class internal to the transport layer which forwards
the request to the appropriate RMI server port.
- Defines properties in the Java virtual machine with the same
names and values as the CGI 1.0 defined environment variables.
3.5.5 Performance Issues and Limitations
Calls transmitted via HTTP requests are at least an order of
magnitude slower that those sent through direct sockets, without
taking proxy forwarding delays into consideration.
Because HTTP requests can only be initiated in one direction
through a firewall, a client cannot export its own remote objects
outside the firewall, because a host outside the firewall cannot
initiate a method invocation back on the client.
CONTENTS | PREV | NEXT
Copyright 1997, 2010, Oracle and/or its affiliates. All rights
reserved.