Explain RMI Architecture?
RMI uses a layered architecture,
each of the layers could be enhanced or replaced without affecting the rest of
the system. The details of layers can be summarised
as follows:
Application Layer: The client and server program
Stub & Skeleton Layer: Intercepts method calls made by the client/redirects
these calls to a remote RMI service.
Remote Reference Layer: Understands how to interpret and manage references made
from clients to the remote service objects.
Transport layer: Based on TCP/IP connections between machines in a network. It
provides basic connectivity, as well as some firewall penetration strategies.
Explain about RMI and it's usage
RMI is one of the distributed computing
technology alternative powered by Java . RMI stands
for Remote Method Invocation ,to keep it simple it means accessing a service
from different node ( i.e., accessing a service provided by an object on server
machine , here an object in client JVM talks with object in the server JVM ).
Java provides an API and base some classes ( in package java.rmi )
to perform these kind of operations .
We basically use this methodology when we need to publish an object at server
side which exposes set of services ( as methods in Object oriented programming
terminology ) and where in one or more clients access these services from
remote machines. By this we are distibuting a common
code in two different JVM's and we are able to access the code on different
JVM.
How do RMI clients contact remote RMI servers?
For an RMI client to contact a remote RMI
server, the client must first hold a reference to the server. The Naming.lookup method call is the most common mechanism by
which clients initially obtain references to remote servers. Remote references
may be obtained by other means, for example: all remote method calls can return
remote references. This is what Naming.lookup does;
it uses a well-known stub to make a remote method call to the rmiregistry, which sends back the remote reference to the
object requested by the lookup method.
Every remote reference contains a server hostname and port number that allow
clients to locate the VM that is serving a particular remote object. Once an
RMI client has a remote reference, the client will use the hostname and port
provided in the reference to open a socket connection to the remote server.
Please note that with RMI the terms client and server can refer to the same
program. A Java program that acts as an RMI server contains an exported remote
object. An RMI client is a program that invokes one or more methods on a remote
object in another virtual machine. If a VM performs both of these functions, it
may be referred to as an RMI client and an RMI server.
Why do I get the
exception "java.net.SocketException: Address
already in use" when I try to run the registry?
This exception means that the port that the RegistryImpl uses (by default 1099) is already in use. You
may have another registry running on your machine and will need to stop it.
How can I make outgoing RMI calls through a local firewall?
There
are three main methods: HTTP tunnelling, SOCKS, and
downloaded socket factories.
HTTP tunnelling
This well-worn method is popular since it requires almost no setup, and works
quite well in firewalled environments which permit you to handle HTTP through a
proxy, but disallow regular outbound TCP connections.
If RMI fails to make a normal (or SOCKS) connection to the intended server, and
it notices that a HTTP proxy server is configured, it will attempt to tunnel
RMI requests through that proxy server, one at a time.
There are two forms of HTTP tunnelling, tried in
order. The first is http-to-port; the second is http-to-cgi.
In http-to-port tunneling, RMI attempts a HTTP POST request to a http: URL
directed at the exact hostname and port number of the target server. The HTTP
request contains a single RMI request. If the HTTP proxy accepts this URL, it
will forward the POST request to the listening RMI server, which will recognize
the request and unwrap it. The result of the call is wrapped in a HTTP reply,
which is returned through the same proxy.
Often, HTTP proxies will refuse to proxy requests to unusual port numbers. In
this case, RMI will fall back to http-to-cgi
tunneling. The RMI request is encapsulated in a HTTP POST request as before,
but the request URL is of the form
http://hostname:80/cgi-bin/java-rmi.cgi?port=n (where hostname and n are the
hostname and port number of the intended server). There must be a HTTP server
listening on port 80 on the server host, which will run the java-rmi.cgi script
(supplied with the JDK), which will in turn forward the request to an RMI
server listening on port n. RMI can unwrap a HTTP-tunneled request without help
from a http server, CGI script, or any other external entity. So, if the
client's HTTP proxy can connect directly to the server's port, then you don't
need a java-rmi.cgi script at all.
To trigger the use of HTTP tunneling, the standard system property http.proxyHost must be set to the hostname of the local
HTTP proxy. (There are reports that some Navigator versions do not set this
property.)
The major disadvantage of HTTP tunneling is that it does not permit inward
calls or multiplexed connections. A secondary disadvantage is that the http-to-cgi method opens a dramatic security hole on the server
side, since without modification it will redirect any incoming request to any
port.
SOCKS
The default implementation of sockets in the JDK will use a SOCKS server if
available and configured. The system property socksProxyHost
must have been set to the hostname of the SOCKS server; if the port number of
the SOCKS server is not 1080, it must be specified in the socksProxyPort
property.
This approach would appear to be the most generally useful solution. As yet, ServerSockets do not use SOCKS, so incoming calls must use
another mechanism.
Downloaded socket factories
This is an innovation in the Java 2 SDK, allowing the server to specify the
socket factory that the clients must use. The clients must be running Java 2
SDK, Standard Edition, v1.2 or later. See the tutorial Using a Custom RMI
Socket Factory for details.
The disadvantage of this approach is that the traversal of the firewall must be
done by code provided by the RMI server side, which does not necessarily know
how that traversal must be done, nor does it automatically have sufficient
privilege to traverse the firewall.
How can I receive incoming RMI calls through a local firewall?
There are three main methods: known ports,
transport-level bridges, and application-level proxies.
Known Ports
If the exported objects are all exported on a known port on a known host, then
that host and port can be explicitly permitted at the firewall. Normally, RMI
asks for port 0 (which is code for "any port"). In the Java 2 SDK,
there is an extra argument to the exportObject method
to specify the exact port number. In JDK v1.1, the server must subclass the RMISocketFactory and intercept requests to createServerSocket(0), replacing it with a request to bind
to a specific port number.
This approach has the disadvantage that it requires the assistance of the
network administrator responsible for the local firewall. If the exported
object is being run in a different location (because code was downloaded to
that site), then the local firewall may be run by network administrators who
don't know who you are.
Transport-level bridges
A transport-level bridge is a program that reads bytes from one TCP connection
and writes them to another (and vice versa) without knowing or caring what the
bytes represent.
The idea here is to export objects in such a way that anyone outside the
firewall who wants to call remote methods on that object instead contacts a
different port (perhaps on a different machine). That different port has a
running program which makes a second connection to the real server and then
pumps bytes each way.
The tricky part is convincing the client to connect to the bridge. A
downloadable socket factory (Java 2 SDK, v1.2 or later) can do this
efficiently; otherwise, it is possible to set the java.rmi.server.hostname
property to name the bridge host and arrange for port numbers to be the same.
Application-level proxies
This approach is quite a bit of work, but leads to a very secure arrangement. A
proxy program runs on a firewall host (one which can be accessed from outside
as well as inside). When an internal server intends to make an exported object
available to the world, it contacts the proxy server and gives it a remote
reference. The proxy server creates a proxy object (a new remote object
residing in the proxy server) which implements the same remote interfaces as
the original. The proxy server returns a remote reference for the new proxy
object to the internal server, which communicates it to the outside world
(somehow).
When an outsider makes a call on the proxy, the proxy immediately forwards the
call to its original object on the internal server. The use of the proxy is
transparent to the outsider (but not to the internal server, who has to decide
whether to pass the original reference or the proxy reference when talking to
anyone).
Needless to say, this requires considerable setup and the cooperation of the
local network administrators.
No comments:
Post a Comment