Distributed Object Application Development: The Java-RMI Solution
This is the second article in a four-part series to be published over the next few weeks. The first was " Link"
The Pros and Cons of RMI
For developing a distributed Internet application, the Java-RMI (Remote Method Invocation) solution is easier to deploy than the alternatives (CORBA and DCOM). However, the benefits of the quick and easy implementation are tempered by a deficiency in a functionality that is critical for most enterprise systems -- multi-language support. Since the Java-RMI solution is less robust then its counterparts, it is best-suited for small, 100% Java applications where legacy database integration is not a requirement and scalability issues are not major concerns.
What really makes Java-RMI attractive is the relative ease with which a developer can get a Java-based distributed application up and running. If a developer is familiar with the Java programming environment, since RMI uses the Java API semantics, the transition to a Java-RMI approach is straightforward. Furthermore, with the Java-RMI methods built in to the JDK1.1 (download-able classes are available for JDK1.02 users), supplemental third-party technologies are not necessary for the development process. Distribution of Java-RMI based applications is also made simpler with the dynamic stub and class-loading capabilities, eliminating the need for clients to have pre-loaded classes installed on their machines.
The Future Of Java RMI
The future of Java-RMI really depends on its ability to communicate with legacy applications and/or CORBA. The reason Java-RMI needs to talk to legacy databases is obvious: they exist in abundance and are still heavily used in most industries. But why CORBA? Because CORBA is drawing more and more industry support and is becoming the "architecture of choice" for most large-scale, distributed applications.
And though the folks at JavaSoft recommend that Java RMI is best suited for distributed computing within the Java domain, there is hope for RMI to break through and integrate with CORBA systems and legacy applications. One source of such hope is the Java Native Interface (JNI). With JDK1.1, the JNI offers Java programmers a new outlet to non-Java applications. JNI provides the capability to interoperate with applications and libraries written in languages such as C/C++ and assembly, enabling Java programmers to take full advantage of code re-use, implement machine specific functionality and connect to legacy systems that previously could not interface with Java applications.
Another source of hope for extending Java RMI connect-ability comes from a partnership between Sun and ILOG. They've produced a product named TwinPeaks, which will take existing C and C++ APIs and generate Java classes that wrap calls to that API in Java classes. This will enable programmers to invoke methods directly to existing APIs from Java and thus eliminate the need for JNI.
On the CORBA front, the folks at JavaSoft and the Object Management Group (OMG), which set the standard for distributed objects development, seem to have agreed to meet on middle ground as they try to get the two technologies to interoperate. JavaSoft declared last June (1997) that they are working on a version of RMI that will incorporate IIOP, and thus make RMI compatible with CORBA systems. At the same time, OMG is discussing the possibilities of extending the current functionality of IIOP so that it will simulate some of RMI's popular features pass-by-value for example. JavaSoft maintains that the existing RMI capabilities will not be compromised when the "IIOPized" version is released for public consumption. Nevertheless, developers using IIOP with RMI will undoubtedly lose some of the standard RMI capabilities. This is due to the fact that the IIOP implementation will use a subset of the normal RMI specification, at least for the near term, since IIOP uses the more generic, common interface definition language.
The bottom line appears to be the following: as RMI moves more toward IIOP and CORBA, and CORBA extends its own functionality to incorporate the most desirable traits of RMI, the two technologies will continue to merge into a single, seamless, distributed object architecture that takes advantage of both RMI's and CORBA's major strengths. So, in one form or another, RMI will continue to be a valuable tool for Java programmers creating distributed object environments.
Sample RMI Based Projects & Applications
- TITLE: Integer Spreadsheet by Athena Design
Integer is the most powerful, easiest to use spreadsheet component for Java. It allows enterprise developers to embed full real-time spreadsheet functionality into their custom applications with little or no code.
- TITLE: IBM San Francisco Project
The San Francisco project is targeted at helping application developers rapidly build distributed, object-oriented applications. It is doing this by providing a base set of object-oriented infrastructure and application logic which can be expanded and enhanced by each developer.
- TITLE: dynamicobjects' perspectives (preview 3)
An integrated, distributed, document manager that includes common components such as a word processor, draw application, a spreadsheet and mail manager.
To help facilitate a general understanding of Java-RMI, a step-by-step illustration of how to implement a working Java-RMI solution using JDK1.1.4 is provided below.
The "TimeStamp" Example
The TimeStamp example application is a basic implementation of Java-RMI. It demonstrates a simple client-server utility where the client requests and receives the current date and time from a remote object located on a server. Figure 2 shows the TimeStamp application distributed-object architecture:
The Java-RMI development process for the TimeStamp example application is broken down to ten manageable steps:
- Create the interface: TimeStampIF.java
- Create the implementation code for the interface: TimeStampImpl.java
- Create the client: TimeStampClient.java
- Compile the interface
- Compile the implementation
- Compile the client
- Run the implementation class through the "rmic" compiler
- Start the RMI registry
- Start the implementation class
- Start the client
Step 1. Create the interface: TimeStampIF.java
The interface will be used to create the client-side stub and server-side skeleton classes, helping to ensure type-consistency between the client and server. A main function of the interface, which is nothing more then a shell structure, is to inform the clients of available methods on the server. The interface for the TimeStamp example is in Listing 1.
Listing 1. The Interface
Step 2. Create the implementation code For the interface: TimeStampImpl.java
The implementation of the interface is the work horse of the Java-RMI distributed object architecture: it contains the actual Java code for all the methods advertised by the TimeStamp interface (TimeStampIF.java). The code for the implementation is provided in Listing 2.
Listing 2. The Implementation
Step 3. Create the client: TimeStampClient.java
The client will invoke remote methods on the server by "looking up" references to the remote object in the server's registry. This is accomplished by employing RMI's Naming service as shown here:
TimeStampIF obj = (TimeStampIF)Naming.lookup [break in code]("rmi://serverNameIP/TimeStampService");
where serverNameIP is the hostname or IP address of the server and TimeStampService is the name of the object that was registered in the TimeStampImpl.java implementation class.
The complete source code for the client is in Listing 3.
Listing 3. The Client
Step 4. Compile the interface
Compile the TimeStampIF.java interface using the JDK1.1 compiler:
Step 5. Compile the implementation
Compile the TimeStampImpl.java implementation using the JDK1.1 compiler:
Step 6. Compile the client
Compile the TimeStampClient.java client using the JDK1.1 compiler:
Step 7. Run the implementation class through the "rmic" compiler
Run the "rmic" compiler on the implementation class (TimeStampImpl.class) which will automatically generate the client-side stub and the server-side skeleton classes. To run the "rmic" compiler, simply type in the following at the command line:
The stub and skeleton files that are generated will be named TimeStampImpl_Stub.class and TimeStampImpl_Skel.class respectively.
Step 8. Start the RMI registry
The RMI registry needs to be started so clients can look up the names of the registered remote objects and thus invoke their corresponding methods. This does not mean, however, that every time a client wishes to call a remote method that it needs to lookup the reference to that method in the RMI registry. This is avoided by employing a remote object, one that has already been established on the client side, to locate other remote objects on the server.
To start the RMI registry, type the following at the command line:
Step 9. Start the implementation class
Start the implementation/server class, TimeStampImpl.class, using the JDK1.1 interpreter:
Step 10. Start the client
Start the client, TimeStampClient.class, using the JDK1.1 interpreter:
If everything goes well, the client will find the remote object, invoke a call on the getTimeStamp method, and be returned the current date and time from the server. When the server successfully returns the requested date/time information back to the client, the client will then print the results to the screen for verification.
Tom Albertson is a senior associate at Coopers & Lybrand Consulting, Government Services Practice in Washington, D.C. He has four years of extensive Internet development experience enhanced by seven years of parallel experience in systems design and engineering, application/GUI development, computer programming and database management. You can reach Tom via email: Tom.Albertson@us.coopers.com.