|
Distributed Computing This website demonstrates using wikis as teaching and learning tool. The course instructor is also happy to share the teaching materials here with those who find it readable. |
Tutorial /
An RMI Daytime ExampleThe remote interfaceWe first develop the remote interface rmidate.Daytime. package rmidate; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.Date; public interface Daytime extends Remote { public Date getDate() throws RemoteException; } Remote interfaces in RMI are required to extend the java.rmi.Remote interface, and remote methods must be declared to throw java.rmi.RemoteException.
Our remote interface Daytime is in the rmidate package and is a sub-interface of Remote. There is only one remote method, namely the getDate method, which throws RemoteException as mandated by the RMI framework.
The remote objectHere is the rmidate.DaytimeImpl class for the remote object. package rmidate; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.Date; public class DaytimeImpl extends UnicastRemoteObject implements Daytime { public DaytimeImpl() throws RemoteException { } public Date getDate() { Date now = new Date(); return now; } } Since this class provides the actual remote functionality, it implements the Daytime interface and the getDate method. The method simply creates a Date object and returns it, effectively passing it to the client program calling this method remotely.
To enable the class to be remotely accessible, it subclasses from the java.rmi.server.UnicastRemoteObject class and provides a constructor that throws RemoteException. The empty constructor implicitly calls super(), or the default constructor of its superclass UnicastRemoteObject, which performs the setup work to allow remote invocation on the object.
The server programOur server program is short and has only a main method. package rmidate; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; public class DaytimeServer { public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException { DaytimeImpl daytime = new DaytimeImpl(); Naming.bind("daytime", daytime); System.out.println("Remote object bound..."); } } All the server does is to create a remote object (new DaytimeImpl()), and then bind it to the RMI registry using the bind method of Naming. The Naming class in the java.rmi package accesses naming services in RMI, including remote object registration and lookup. In particular, the bind method binds a name (String) to a remote object in the registry so that a later call to the lookup method with that name retrieves the remote object. I will further explain the RMI APIs later in this section.
The main method is declared to throw exceptions arisen from the constructor of DaytimeImpl (RemoteException) and the bind method (AlreadyBoundException, MalformedURLException).
The client programThe client program lookups and invokes the remote object in its main method. package rmidate; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.util.Date; public class DaytimeClient { public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException { String regServer = args.length > 0 ? args[0] : "localhost"; String lookupName = "rmi://" + regServer + "/daytime"; Daytime daytime = (Daytime) Naming.lookup(lookupName); Date serverNow = daytime.getDate(); System.out.println("Server time is " + serverNow); } } To lookup the remote object, we need to specify the host name of the RMI registry and the registered name of the remote object in the registry. For example, with the string ‘rmi://localhost/daytime’ as the parameter, the lookup method of Naming obtains a remote reference to the remote object named ‘daytime’ in the RMI registry running on localhost.
As the return type of the lookup method is Remote, casting to our remote interface Daytime is performed on assigning to the daytime variable. After that, we can invoke the getDate method on daytime. Though the call to daytime.getDate() appears to be a local method call, it is in fact a remote invocation and the Date instance is returned from the remote object. In other words, the Date instance is the time at the machine running the remote object rather than that running the client program .
Now, you’ve seen the program components of the daytime RMI application. Work on activity below to test the application and then complete the following questions to check your understanding of the basic RMI principles.
Your TasksIn this activity, you execute and test the daytime RMI application. Assume the bin path of JDK is in the PATH, and the 4 source files Daytime.java, DaytimeClient.java, DaytimeImpl.java and DaytimeServer.java are in the directory t:\src. Perform the following steps. Step 1: Change to the directory t:\src. Make a directory ‘server’ for the class files in the server and a directory ‘client’ for the class files in the client. t:\> cd /d t:\src
t:\src> md server
t:\src> md client
Step 2: Compile the programs used in the server and place the generated class files in the ‘server’ directory (in 1 line): t:\src> javac -d server Daytime.java DaytimeImpl.java DaytimeServer.java Step 3: Complete the programs used in the client and place the generated class files in the ‘client’ directory (in 1 line): t:\src> javac -d client Daytime.java DaytimeClient.java Step 4: Open a new DOS window. Start the RMI registry server rmiregistry in JDK by executing the following command: t:\src> rmiregistry Step 5: Open a new DOS window. Execute the daytime server (in 1 line): t:\src> java -cp server -Djava.rmi.server.codebase=file:t:/src/server/ rmidate.DaytimeServer We use the java.rmi.server.codebase property to specify the directory containing the class files. It is required so that the RMI registry server rmiregistry can locate the class files of the remote objects.
Step 6: Execute the daytime client program to test the application (in 1 line): t:\src> java -cp client rmidate.DaytimeClient Questions1. The definition of a remote interface must involve one interface and one class in the Java API. What are they?
2. To enable remote accessibility, what class should be extended by a class of remote object? How should you define the constructor of a class of remote object?
3. What API can be used to register the name of a remote object in an RMI registry?
4. How do clients obtain a reference to the remote object?
|