|
Remote Method Invocation (RMI) Key point: Single object model reduces complexity. Key point: CORBA is designed to integrate objects among distinct languages. Source: http://java.sun.com/features/1997/nov/rmi.html Statement from SUN http://java.sun.com/pr/1997/june/statement970626-01.html
Tutorial from: http://java.sun.com/products/jdk/1.1/docs/guide/rmi/getstart.doc.html Getting Started Using RMIThis chapter shows you the steps to follow to create a distributed version of the classic Hello World program using Java Remote Method Invocation (RMI). The distributed Hello World example uses an applet to make a remote method call to the server from which it was downloaded to retrieve the message "Hello World!". When the applet runs, the message is displayed on the client. To accomplish this, you will work through the following three lessons:
Write The HTML and Java Source FilesThere are four source files for the Hello World server and applet:
Because the Java language requires a mapping between the fully
qualified package name of a class file and the directory path to
that class, before you begin writing Java code you need to decide
on package and directory names. (This mapping allows the Java
compiler to know the directory in which to find the class files
mentioned in a Java program.) For the Hello World program
developed in this chapter, the package name is For example, to create the directory for your source files on Solaris, execute this command: mkdir $HOME/jdk1.1/mysrc/examples/hello Define a Remote InterfaceRemote method invocations can fail in very different ways from local method invocations, due to network related communication problems and server problems. To indicate that it is a remote object, an object implements a remote interface, which has the following characteristics:
Here is the interface definition for Hello World. The
interface contains just one method, package examples.hello; public interface Hello extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException; } Write an Implementation ClassTo write a remote object, you write a class that implements one or more remote interfaces. The implementation class needs to:
For example, here is the source for the package examples.hello; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloImpl extends UnicastRemoteObject implements Hello { private String name; public HelloImpl(String s) throws RemoteException { super(); name = s; } public String sayHello() throws RemoteException { return "Hello World!"; } public static void main(String args[])
{
// Create and install a security manager
System.setSecurityManager(new RMISecurityManager());
try {
HelloImpl obj = new HelloImpl("HelloServer");
Naming.rebind("//myhost/HelloServer", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
Implement a Remote InterfaceThe implementation class for the Hello World example is public class HelloImpl implements Hello extends java.rmi.server.UnicastRemoteObject Extending Define the Constructor for the Remote ObjectThe constructor for a remote class is no different than the constructor for a nonremote class: it initializes the variables of each newly created instance of the class. Here is the constructor for the private String name; public HelloImpl(String s) throws java.rmi.RemoteException { super(); name = s; } Note the following:
Although the call to the Provide an Implementation for Each Remote MethodThe implementation class for a remote object contains the code that implements each of the remote methods specified in the remote interface. For example, here is the implementation for the public String sayHello() throws RemoteException { return "Hello World!"; } Arguments to, or return values from, remote methods can be of
any Java type, including objects, as long as those objects
implement the interface
A class can define methods not specified in the remote interface, but those methods can only be invoked within the virtual machine running the service and cannot be invoked remotely. Create and Install a Security ManagerThe System.setSecurityManager(new RMISecurityManager()); A security manager needs to be running so that it can guarantee that the classes loaded do not perform "sensitive" operations. If no security manager is specified, no class loading for RMI classes, local or otherwise, is allowed. Create One or More Instances of a Remote ObjectThe HelloImpl obj = new HelloImpl("HelloServer"); The constructor exports the remote object, which means that once created, the remote object is ready to begin listening for incoming calls. Register a Remote ObjectFor a caller (client, peer, or applet) to be able to invoke a method on a remote object, that caller must first obtain a reference to the remote object. Most of the time, the reference will be obtained as a parameter to, or a return value from, another remote method call. For bootstrapping, the RMI system also provides a URL-based
registry that allows you to bind a URL of the form For example, the following code binds the URL of the remote
object named Naming.rebind("//myhost/HelloServer", obj); Note the following about the arguments to the call:
For security reasons, an application can bind or unbind only in the registry running on the same host. This prevents a client from removing or overwriting any of the entries in a server's remote registry. A lookup, however, can be done from any host. Write an Applet that Uses the Remote ServiceThe applet part of the distributed Hello World example
remotely invokes the HelloServer's package examples.hello; import java.awt.*; import java.rmi.*; public class HelloApplet extends java.applet.Applet { String message = ""; public void init() { try { Hello obj = (Hello)Naming.lookup("//" + getCodeBase().getHost() + "/HelloServer"); message = obj.sayHello(); } catch (Exception e) { System.out.println("HelloApplet exception: " + e.getMessage()); e.printStackTrace(); } } public void paint(Graphics g) { g.drawString(message, 25, 50); } }
The constructed URL must include the host. Otherwise, the
applet's lookup will default to the client, and the Write the Web Page that Contains the AppletHere is the HTML code for the web page that references the Hello World applet: <HTML> <title>Hello World</title> <center> <h1>Hello World</h1> </center> The message from the HelloServer is: <p> <applet codebase="../.." code="examples.hello.HelloApplet" width=500 height=120> </applet> </HTML> Note the following:
codebase="../.." The codebase in this example specifies a directory two levels above the directory from which the web page was itself loaded. Using this kind of relative path is usually a good idea.
code="examples.hello.HelloApplet" Compile and Deploy Class Files and HTML FilesThe source code for the Hello World example is now complete
and the
In this section, you compile the When you use the Some Web servers allow accessing a user's public_html directory via an HTTP URL constructed as "http://host/~username/". If your Web server does not support this convention, you may use a file URL of the form "file://home/username/public_html". Compile the Java Source FilesMake sure that the deployment directory To compile the Java source files, run the javac -d $HOME/public_html/codebase Hello.java HelloImpl.java HelloApplet.java This command creates the directory Generate Stubs and SkeletonsTo create stub and skeleton files, run the For example, to create the stub and skeleton for the HelloImpl
remote object implementation, run rmic -d $HOME/public_html/codebase examples.hello.HelloImpl The
Note that the generated stub implements exactly the same set of remote interfaces as the remote object itself. This means that a client can use the Java language's built-in operators for casting and type checking. It also means that Java remote objects support true object-oriented polymorphism. Move the HTML File to the Deployment DirectoryTo make the web page that references the applet visible to
clients, the mv $HOME/jdk1.1/mysrc/examples/hello/index.html $HOME/public_html/codebase/examples/hello Set Paths for RuntimeMake sure that the $ Start the Remote Object Registry, Server, and AppletStart the RMI Bootstrap RegistryThe RMI registry is a simple server-side bootstrap name server that allows remote clients to get a reference to a remote object. It is typically used only to locate the first remote object an application needs to talk to. That object in turn will provide application specific support for finding other objects. To start the registry on the server, execute the start rmiregistry (Use And on Solaris: rmiregistry & The registry by default runs on port 1099. To start the registry on a different port, specify the port number in the command. For example, to start the registry on port 2001 on Windows NT: start rmiregistry 2001 If the registry is running on a port other than the default,
you need to specify the port number in the URL-based methods of
the Naming.rebind("//myhost:2001/HelloServer", obj); Similarly, the URL stored on the web page needs to specify the nondefault port number, or else the applet's attempt to look up the server in the registry will fail: <PARAM name="url" value="//myhost:2001/HelloServer"> You must stop and restart the registry any time you modify a remote interface or use modified/additional remote interfaces in a remote object implementation. Otherwise, the class bound in the registry will not match the modified class. Start the ServerWhen starting the server, the The following command shows how to start the HelloImpl server, specifying this property: java -Djava.rmi.server.codebase=http://myhost/~myusrname/codebase/ examples.hello.HelloImpl & The trailing A stub class is dynamically loaded into a client's virtual machine only when the class is not already available locally. Run the AppletOnce the registry and server are running, the applet can be run. An applet is run by loading its web page into a browser or appletviewer, as shown here: appletviewer http://myhost/~myusrname/codebase/examples/hello/index.html & After running the appletviewer, you will see output similar to the following on your display: |