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 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.
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.
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.
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.
import java.rmi.*;public class TimeStampClient < static public void main(String args[])< // variable to store the information provided by remote object String whatTimeIsIt; // attempt to call the remote object try < // obtain a reference to the remote object in the registry TimeStampIF obj = (TimeStampIF)Naming.lookup("rmi://serverNameIP/TimeStampService"); // invode the remote method (getTimeStamp) and store the resultswhatTimeIsIt = obj.getTimeStamp(); System.out.println("TimeStamp = "+whatTimeIsIt); >catch (Exception e) < // and if it fails. System.out.println("TimeStampService exception: " + e.getMessage()); e.printStackTrace(); >// end try/catch exeception > // end main> // end TimeStampClient.class-->
javac TimeStampIF.java.
javac TimeStampImpl.java.
javac TimeStampClient.java.
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:
rmic TimeStampImpl
The stub and skeleton files that are generated will be named TimeStampImpl_Stub.class and TimeStampImpl_Skel.class respectively.
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:
rmiregistry
java TimeStampImpl
java TimeStampClient
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.