Monday, September 7, 2009

Java RMI Interview Questions

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.

1

2

3

4

5

6

7

8

 

No comments:

Post a Comment