Download Assignment 3: Appendix RMI programming tutorial

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Spring Term 2013
Assignment 3: Appendix
RMI programming tutorial
In this tutorial, we will give an example of a RMI client and server. The server exposes a remote
method int addOne(int i) to the clients. With the input arguments i from clients, addOne()
simply returns i+1. To create and run the RMI example, the following steps are necessary:
1
Designing a Remote Interface
The interface defines the methods that can be invoked from the client. Essentially, the interface defines the client’s view of the remote object. The example.Calculator interface defines the
remotely accessible part. Here is the source code:
package calculator;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Calculator extends Remote {
public int addOne(int i) throws RemoteException;
}
By extending the interface java.rmi.Remote, the Calculator interface identifies itself as an
interface whose methods can be invoked from another Java virtual machine.
As a member of a remote interface, the addOne(int i) method is a remote method. Therefore,
this method must be defined as being capable of throwing a java.rmi.RemoteException. This
exception is thrown by the RMI system from a remote method invocation to indicate that either
a communication failure or a protocol error has occurred. A RemoteException is a checked
exception, so any code invoking a remote method needs to handle this exception by either catching
it or declaring it in its throws clause.
2
2.1
Creating a RMI server
Implementing a Remote Interface
The example.CalculatorImpl class implements the remote interface Calculator. Here is the
source code for the CalculatorImpl class:
package server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import calculator.Calculator;
public class CalculatorImpl implements Calculator {
public CalculatorImpl() throws RemoteException {
UnicastRemoteObject.exportObject(this, 0);
}
public int addOne(int i) throws RemoteException {
return i + 1;
}
}
The UnicastRemoteObject.exportObject(this, 0) method 1 exports the Remote object to the
RMI runtime, so that it is made available to receive incoming remote invocations from clients.
This is only one part of the setup procedure, which
• Export one or more remote objects
• Register at least one remote object with the RMI registry
We still need to register the remote objects with the RMI registry. These two parts of the setup
procedure can be either encapsulated in a method of the remote object implementation class itself
(like the Hello World example 2 ) or included in another class entirely. In this example, we create
a separate server class CalculatorServer.java to do this:
package server;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import server.CalculatorImpl;
public class CalculatorServer {
public static void main(String[] args) {
try {
String name = "Calculator";
CalculatorImpl c = new CalculatorImpl();
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, c);
System.out.println("CalculatorServer Ready!");
} catch (Exception e) {
System.err.println("CalculatorServer exception:");
e.printStackTrace();
}
}
}
The java.rmi.registry.Registry remote interface is the API for binding (or registering) and
looking up remote objects in the registry. The java.rmi.registry.LocateRegistry class provides static methods for synthesizing a remote reference to a registry at a particular network
address (host and port). Through registry.rebind(name , c), the CalculatorServer class
adds the Calculator object with name "Calculator" to the RMI registry running on the server.
1 http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/server/UnicastRemoteObject.html
2 http://java.sun.com/j2se/1.5.0/docs/guide/rmi/hello/hello-world.html
2
3
Creating a RMI client
The RMI client constructs a name to look up a Calculator remote object, the same name used by
CalculatorServer to bind its remote object. Also, the client uses the LocateRegistry.getRegistry
API to synthesize a remote reference to the registry on the server’s host. The value of the first
command-line argument, args[0], is the name of the remote host on which the Calculator object
runs. The client then invokes the lookup method on the registry to look up the remote object by
the name, which is args[1], in the server host’s registry. The value of the third command-line
argument, args[2], is the input parameter for the remote method addOne(int i).
package client;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import calculator.Calculator;
public class CalculatorClient {
public static void main(String args[]) {
try {
Registry registry = LocateRegistry.getRegistry(args[0]);
Calculator cal = (Calculator) registry.lookup(args[1]);
int input = (new Integer(args[2])).intValue();
int output = cal.addOne(input);
System.out.println("The output of addOne(" + input + ")" + " is " + output);
} catch (Exception e) {
System.err.println("CalculatorClient exception:");
e.printStackTrace();
}
}
}
4
Compiling and running the example
a) Compile .java files:
bash$ javac calculator/*.java client/*.java server/*.java
b) Start rmiregistry and leave it running in the background, and start the server:
bash$ rmiregistry &
bash$ java server.CalculatorServer
Note: Kill old rmiregistry before starting new one!
c) Running the client:
bash$ java client.CalculatorClient localhost Calculator 100
d) The result is then displayed:
The Output of addOne(100) is 101
e) Remarks:
As of the J2SE 5.0 release, by default, rmic does not generate any skeleton classes. Moreover, stub classes for remote objects no longer need to be pregenerated using the rmic stub
compiler, unless the remote object needs to support clients running in pre-5.0 VMs. If your
3
application needs to support such clients, you will need to generate stub classes for the remote objects used in the application and deploy those stub classes for clients to download.
For details on how to generate stub classes, see the tools documentation for rmic [Solaris3 ,
Windows4 ]. For details on how to deploy your application along with pregenerated stub
classes, see the codebase tutorial 5 .
4.1
Further reading
Find a more interesting example of using RMI’s unique capabilities to load and to execute userdefined tasks at runtime here: http://java.sun.com/docs/books/tutorial/rmi/index.html
3 http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/rmic.html
4 http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/rmic.html
5 http://java.sun.com/j2se/1.5.0/docs/guide/rmi/codebase.html
4