J2EE Tutorial - RMI Example
Around 1990, the OMG (Object Management Group) was formed by just EIGHT founder members.( SUN MICROSYSTEMS, HEWLETT-PACKARD, Unisys Corporation, Philips Telecom, Data General, 3Com Corporation , American Aitlines and Canon . OMG developed the CORBA standard.( Common Object Request Broker Architecture).The membership grew into nearly 800 , which includes all the big names in the Enterprise computing world .( except Microsoft).Corba is just a specification. The required Interace is defined in a C-like language known as OMG-IDL. The IDL is a contract. It is like a function declaration in C++. The name of the method, the type of parameters required and the type of return value are specified by the IDL file. Typically, an IDL compiler 'compiles' this IDL file into the language chosen ( it may be C++ or Java ). The idl compiler ,in reality translates the IDL interface into a real language like C++ or Java. Much more important, it automatically generates what are known as 'Stub' & 'Skeleton' files .Companies like IONA ORBIXWEB, VISIGENIC, MICO, JAC-ORB specilaised in creating such IDL-COMPILERS.
That was the period between 1991 and 1996. Java had not yet arrived and C++ was the language of choice for Enterprise work, besides COBOL, ADA ( for real time systems) & SMALLTALK. The earliest Corba language bindings were for these languages.The characteristic feature of Distributed Object Technologies is that the client invokes the method of an object which resides in a remote server in its own workspace, as if the object resided locally.
Why is this so important? Why not just pass parameters to the remote object and invoke the function in remote server itself? Please read on.
That is where the relevance of 'Distributed Objects ' technology becomes evident. If the author of the remote object ( wriiten in C++) wants his object to be accessible to other clients, he can start with the IDL file at his end and publish the idl to others. Using the IDL file, others can create the Stub &skeleton .and they can write their own clients to use the remote object.
Thus, the remote object's location is not disturbed.Its implementation details are not revealed. It can be written in any language , suitable for the specific application realm.( As they say, Java is no 'Silver Bullt' (ie) a solution suitable for all situations. Legacy objects can still be used. It may be running on any platform.
In the Corba approach, the stub and skeleton source files are automatically created by the IDL compiler. The component designer, then creates an implementation for the interface. During compilation, the stub and skeleton files are referenced.The client file requires information about the stub. After these steps, the class files are installed in both ends, as appropriate. Now the client is able to invoke the remote object's methods from its own workspace.Actually, the remote object after being created is registered in Corba Naming Service.The client simply enquires the Naming service for the remote object , by 'name'.This is known as 'Location Transparency'.
Why is 'Location Transparency' important? For Security? No.
A server is supposed to work 24X7 ( a fancy way of saying 'continuously'). If for some reason , there is some problem in the server, the remote server's administrator can transfer the classes to another machine without disturbing the service.In Enterprise world, Location transparency is essential. Imagine a continuously touring businessman who informs his current contact number to the enquiry desk and if we want to contact him, we have to get his current whereabouts from the enquiry desk.( read 'Naming service').
The other important characteristic of Interface approach is what is usually referred to as ' Immutability of Service Contract'. , in COM circles. All that it means is that the corba provider can improve the implementation if desired without disturbing the contract with the client. This is an important merit of 'Interface-based'approach over 'Class-based ' approach.
SUN MICROSYSTEMS being one of the founder members of the OMG (Object Management Group)which created the CORBA specification , aimed at providing simple API for creating CORBA-compliant RemoteObjectServers , using just the Java language. (ie) the aim is to develop RemoteObjectServers, which can be invoked and used by client programs written in other languages and working in different platforms. As Java language is already platform independent, the only problem was that of the language of the client.
With an eventual aim of creating a simple version of Corba-compliant server , using nothing but Java, Sun began the journey with RMI. Remote Method Invocation is a corba-like solution in its approach. It begins with interface . It then creates an implementation class. Using this, it creates the Skeleton class file (Skeleton is the proxy for the RemoteObject in the server side). and also 'Stub ' class file.(Stub is the proxy for the Remote Object in client side). The remote object is registered in the Remote Registry.& waits for the client's call. All this was very much similar to Corba.( However, there is no location transparency in RMI).
RMI requires Java at both ends. Many programmers have asked in web forums why we cannot simply use the socket method instead of RMI. It is true that the merit of Interface approach is not all that evident if we have Java at both ends. But, even within that constraint, experienced programmers advise that if our program involves a lot of complex objects created by us and passed as parameters to the server, it is advisable to use the RMI method as it will take care of the Serialization details.
Apart from this, we gain a better insight if we consider RMI as just a first step towards RMI-IIOP, which enables us to write Corba-compliant servers without the hassle of learning OMG-IDL. When we are experienced in writing RMI programs, we can easily switch over to RMI-IIOP. The merit of RMI-IIOP is that we write just a java file and the RMI compiler which comes with JDK1.3 can create the IDL from this file!
This is known as 'Quick Corba'. ( Previously, Visigenic company had provided a software known as Caffiene , along the same lines.) Many earlier books like ' Java Distributed Objects' & 'Developing Servlets' by James Goodwill refer to that. That role is being done by RMI-IIOP now.
The advantage of RMI-IIOP is that the programmer does not need to know anything about OMG-IDL. He simply writes a program with very slight changes from RMI style. He can get the IDL file automatically generated by the IDL compiler. This IDL file can be distributed for CORBA clients.They can use their own IDL compiler suitable for their platform and language and still use our java server.
(RMI--IIOP was developed jointly by SUN & IBM).
We will now see how the same interface can be used to create an RMI program and then an RMI-IIOP program.
Let us now consider the RMI version of the 'greeter' program.
RMI PROGRAM...HOW TO CREATE & RUN?
=================================
From a DOS window, create a folder as c:\greeter
cd to c:\greeter
----
>set path=c:\windows\command;c:\jdk1.3\bin
>set classpath=c:\greeter
-----
Edit greeterinter.java ( This is the Interface file).
import java.rmi.*; 0
public interface greeterinter extends Remote
{
String greetme(String s) throws RemoteException; 1
}
---------------------------------------------------------------------
compile this file. 2
>javac greeterinter.java
We get greeterinter.class file after compilation.
----------------------------------------------------------- 3
Next, edit the implementation file as follows:
//greeterimpl.java
import greeterinter.*; 4
import java.rmi.*;
import java.rmi.server.*; // essential. do not omit.
public class greeterimpl extends UnicastRemoteObject 5
implements greeterinter
{
public static void main(String args[]) 6
{
// System.setSecurityManager(new RMISecurityManager() );
try 7
{
greeterimpl app = new greeterimpl();
Naming.rebind("//" + "localhost" + "/greeterinter", app); 8
System.out.println("greeter is registered");
}
catch(Exception ex) 9
{
System.out.println("point1 "+ex);
} 0
}
//==============================================
public greeterimpl() throws RemoteException 1
{
}
//================================================ 2
public String greetme(String s) throws RemoteException
{
return("How are you?......"+s); 3
}
}
//over. 4
-------------------------------------------------------------------
Now, compile greeterimpl.java
>javac greeterimpl.java 5
We get greeterimpl.class
------------------------------------
The next step is to create the class files for the Stub & Skeleton 6
using the rmic.exe provided in jdk.
>rmic greeterimpl
You will find that this command automatically creates the class files 7
for Stub & Skeleton.
--------------------------------------------------------
We can now create the servlet file as follows, which will be the client for the RMI server. 8
--------------------------
greeterclientservlet.java
import greeterinter.*; 9
import greeterimpl.*;
import greeterimpl_Stub.*;
import greeterimpl_Skel.*; 0
import java.net.*;
import java.rmi.*;
import javax.servlet.*; 1
import javax.servlet.http.*;
import java.io.*;
import java.util.*; 2
public class greeterclientservlet extends HttpServlet
{
greeterinter server; 3
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException 4
{
response.setContentType("text/html");
PrintWriter out = response.getWriter(); 5
String s = request.getParameter("text1");
try
{ 6
server =(greeterinter) Naming.lookup("//" + "localhost" + "/greeterinter");
// Protocol is left unspecied.Normally it is JavaRemoteMethod Protocal
// If there are firewall restrictions , it automatically 7
// switches over to http .
}
catch (Exception e1) {out.println(""+e1);} 8
String s1 = server.greetme(s);
System.out.println(s1);
out.println("<html>"); 9
out.println("<body>");
out.println(s1);
out.println("</body>"); 0
out.println("</html>");
}
} 1
-----------------------------------------------------------------------
To compile the servlet, change the classpath as follows:
>set classpath=%classpath%;c:\jsdk2.0\src 2
--
Now we will be able to compile the servlet.
------------------------------------------------------------ 3
Create the html file to invoke the above servlet.
greeterclientservlet.htm
<html> 4
<body>
<form method=post action='http://localhost:8080/servlet/greeterclientservlet'>
<input type=text name='text1'> 5
<input type=submit>
</form>
</body> 6
</html>
================================
Now copy greeterclientservlet.htm to c:\tomcat\webapps\root 7
Copy all the class files in c:\greeter to c:\tomcat\webapps\root\web-inf\classes
---------------
Now, we are ready to execute our RMI-servlet program. 8
====
c:\greeter>start rmiregistry
This command creates a blank window. Minimize it. 9
In the same DOS window,
>java greetserverimpl
-- 0
This starts the remote server . The remote object is created and
registered in the RMI registry in the remote server.
We get a message informing us about it. 1
The implementation program creates an instance of the class and registers the instance in the RMI REGISTRY in the remote server, by the identity of 'greeterinter'.
// Naming.rebind("//" + "localhost" + "/greeterinter", app);
Remember to start the 'Tomcat' server as before. 2
Now , we start the InternetExplorer and type the URL as
'http://localhost:8080/greeterclientservlet.htm'
------------ 3
We get a form. Fill up your name in text1 and submit.
---
The data is sent to the servlet. The servlet program looks up at the 4
Registry to locate the object by name 'greeterinter'.
After getting an instance.by 'Naming.lookup' , it invokes the 'greetme' function on the object and passes the string from the form as paramter to the method called. The method call with parameter is passed to the stub.The stub sends it to the Skeleton.The skeleton sends it to the remoteobject in remote server. The remote object executes the function there and sends the result to skeleton. The skeleton sends it to stub. The stub sends it to the servlet. The servlet sends the result to the browser.
********************************************************************************** 5
( For reasons of space , we are constarined to limit ourselves to this much.
If you need a more elaborate treatment, the books by Jaworsky and the one by
Bill McCarty are ideal). 6
******************************************************************************
Let us now see how, an RMI-IIOP program is developed.
This part is very unique and important. You may not find this in any textbook, 7
because , RMI-IIOP was introduced only in JDK1.3 and most of the Java books in
circulation deal only with JDK1.2.Sun's tutorial is not much helpful. So, read carefully.
----------------------------------------------------------------------------- 8
Here ara a few lines from Sun's documentation on RMI--IIOP.
'RMI lacks interoperability with other languages, and because it uses a non-standard communication protocol, cannot communicate with CORBA objects.
IIOP is CORBA'S communication protocol.It defines the way in which the bits are sent over a wire between CORBA clients and servers. 9
Previously Java programmers had to choose between RMI and JavaIDL.for Distributed programming solution. Now, by adhering to a few restrictions, RMI objects can use the IIOP protocol.( Internet InterOperable Protocol) and communicate with CORBA objects.
Thus, RMI-IIOP combines RMI-style ease of use with CORBA cross-language interoperability.
To resume, 0
We will need 4 files (ie)
a) greeter.java ( the Interface file)
b) greeterimpl.java ( the implementation file) 1
c) greeterclientservlet.java ( the servlet which invokes the remote server)
d) greeterclientservlet.htm ( the html file to invoke the servlet)
These files have been given below.( Carefully compare these files with their RMI counterpart to appreciate the similarity and minute dfferences).