using javaRemote Method Invocation
by Prithvi Rao
Prithvi Rao is the founder of Kiwilabs, which specializes in
software engineering methodology and Java training. He has worked on
the development of the MACH OS and a real-time version of MACH, and he
holds two patents resulting from his work on mobile robots.
This article presents a simple RMI example that walks the reader through the steps required to write such applications. Summary of Java RMI Remote invocation is nothing new. For instance, C programmers have used Remote Procedure Call (RPC) semantics to execute a C function on a remote host. What makes RMI different is that in Java it is necessary to package both data and methods and ship both across the network. (RPC works on data structures primarily.) This implies that the recipient must be able to interpret the object after receiving it. RMI at a glance: The Good
The Bad
The Ugly
Although RMI does not directly support other languages, it is possible to use the Java Native Interface (JNI) to create Java wrappers that can be used with RMI. Of course this introduces yet another level of indirection and may further exacerbate performance problems that are due to scaling. Java RMI Example The following example demonstrates the use of RMI within applets, which is a typical use of Java and RMI. It is conceivable that an applet (which is a Java program running within the context of a browser such as Netscape, appletviewer, or HotJava) needs to invoke methods on objects that are on other machines. Consider a database application, for instance, with a GUI that is an applet and a data server that is multithreaded and written in Java. The GUI runs on a thin client, and the data server may run on another machine across a network. This is a fairly common scenario and so our example is not atypical. There are really two Java Virtual Machines (JVMs) involved in this example. The first JVM is the one into which the applet is loaded. The other JVM is the one on which the remote object exists. Let's think of the first JVM (the one running the applet) as the local side. I have avoided the use of "client and server" because there is really no client-server relationship here. It really is a case of one JVM making another JVM do something. The client-server abstraction exists at the level of the application and not at the level of RMI. Another way to look at this is that one JVM is invoking methods on an object running on another JVM. Let's look at the code for an applet. This is the local side. This file is called HelloApplet.java. package example.hello; This means that the Hello class is in a package examples.hello. Remember that this is interpreted as a directory relative to CLASSPATH. import java.awt.*; This is necessary because we are writing an applet, and applets are part of the Abstract Windowing Toolkit (AWT). (See my ;login: April 1999 article for an AWT example.) import java.rmi.*; This is new. java.rmi is a package that provides support for RMI, and so we must import it. public class HelloApplet extends java.applet.Applet { We are extending applet, except that because we did not import java.applet we must provide the fully qualified name (fqn) for the applet class we wish to extend. String message = ""; Field for the message that will be received from the remote object. public void init() { The init method for the applet.
try {
This creates an instance of the remote object inside the remote JVM. We will say more about this later. It is important to note that this method returns an instance of a class Hello. The argument it takes is a URL, or so it seems because of the '//'. message = obj.sayHello(); This statement invokes the method sayHello() of the remote object.
} catch (Exception e) {
Naming.lookup throws three exceptions, so we must catch them.
}
Draw the string that was received from the remote object on the screen. Now let's take a look at the remote side. There are two files associated with the remote side. The first is Hello.java. package examples.hello; Put this in the same package as the applet. public interface Hello extends java.rmi.Remote { Define an interface called Hello that extends java.rmi.Remote. We will explain this later. Basically, if an object wants to be a remote objectthat is, it wants to be able to be invoked by some other objectthen it must implement the interface java.rmi.Remote.
{
It must also specify those methods that can be invoked remotely. In this case there is only one such method, sayHello. Recall that the applet HelloApplet calls a method by this name. This is the method that will be invoked. At this point it is merely a method of an interface and has only a signature but no body. Now the second of the two files for the remote side. This is called HelloImpl.java.
import examples.hello.*;
All servers must be subclasses of this if they want to be remote. public class HelloImpl extends UnicastRemoteObject implements Hello { This implements the interface Hello, and since Hello extends the Remote interface, this makes HelloImpl a class of type Remote. private String name; This is the name by which this object is known to the other objects that wish to invoke it.
public HelloImpl(String s) throws java.rmi.RemoteException
{
The constructor for this class.
public String sayHello() throws RemoteException {
Recall that the sayHello method is part of the interface Hello. Since this class implements that interface, it must provide a definition for it. The definition simply returns the string "Hello World." public static void main(String args[]) This application's main function. Recall that applets do not need main. System.setSecurityManager(new RMIsecurityManager()); Remember that applications can set their security manager (;login:, August 1998). The object that invokes methods on this JVM should not be allowed to roam free on the host machine on which this JVM is executing. The RMI security manager enforces a suitable security policy. Recall that the applet invoking a method on this object might send it data that might be bytecode that is capable of being executed. For this reason it is necessary to ensure the presence of the security manager.
try {
Instantiate a HelloImpl and call it HelloServer. Recall that the applet used Naming.lookup().
Naming.rebind("HelloServer", obj);
Register this object as existing and print out some diagnostics.
} catch (Exception e) {
Running the Example
Conclusion The use of distributed objects is fairly common in many IT application domains. Two examples are the health-care industry and the stock market. In most cases where distributed objects are used, it is necessary to create an infrastructure in which Java and non-Java objects can invoke methods on each other. In these cases Java RMI cannot be used without first writing some kind of Java "wrapper" for the non-Java code. These implementations therefore use CORBA or DCOM. If a pure Java application is envisaged, then Java RMI is a good choice for its ease of use and its ability to facilitate the rapid prototyping of the application.
In future articles we will demonstrate the capability of Java with
other middleware packages. There is no substitute for being well
informed in order to make intelligent decisions, and Java RMI is only
one piece of the puzzle.
|
Need help? Use our Contacts page.
Last changed: 16 Nov. 1999 mc |
|