Download 9. Introducing Java RMI

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
Concurrent & Distributed Systems
PRACTICAL 9 – Java Remote Method Invocation (RMI)
Introduction to RMI
This practical looks at the Java based model for inter-object communication using Java RMI.
With this model a client program can invoke methods of objects that reside on a different
machine from the client program. RMI is useful only for communication between Java objects
(i) Stubs – When client code wants to invoke a method on a remote object, it actually calls a
regular Java method that is encapsulated in a surrogate object called a stub. Normally the
stub resides on the client machine, and sends the information in packaged form to the
server. On the server side, a skeleton object makes sense out of the information contained
in the package and passes that information to the actual object executing the remote
method. In the current version of Java the stub can be generated dynamically (at run time)
and exported (published) by the server so that connecting clients can get a reference to the
stub and call the methods remotely.
(ii) Setting up RMI – Running even the simplest remote object example requires quite a bit
more setup than does running a standalone Java program. The necessary information
must be separated into client-side development and server-side implementations.
(Note. See http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/ for further details.)
Question 1 ( RMI via “localhost”)
To get started with actual coding, we walk through a simple example that generates two objects
of type Product on the server computer. The client computer will run a Java program that
locates and queries these objects.
Step 1 (Develop and place the interface class on the server and client)
The client must know what it can do with these objects. The object capabilities are expressed in
an interface that is shared between the client and server. Compile this interface.
//Interface to Product objects - shared between client and server
import java.rmi.Remote;
import java.rmi.RemoteException;
interface Product extends Remote {
public String getDescription() throws RemoteException;
} // end Product
(Note. Remote method invocations can fail in many additional ways compared to local method
invocations (such as network related communication problems and server problems) and
remote methods must report such failures by throwing a java.rmi.RemoteException)
Step 2 ( Develop and place the implementation class on the server)
Next consider the server side. You must first implement the class that actually carries out the
1
methods advertised in the remote interface.
// This server implementation class carries out the methods advertised in the
// Product remote interface
public class ProductImpl implements Product {
private String descr;
// default constructor
public ProductImpl() {
super();
} // end constructor
// class constructor
public ProductImpl(String d)
descr = d;
} // end constructor
{
public String getDescription() {
return "I am a " + descr + ". Buy me!";
} // end setDescription
} // end ProductImpl
Note. The class has a single method getDescription(), that can be called from a remote client.
Step 3 (Develop a server program that creates and registers objects)
This server program registers two Product objects under the names “MyToaster” and
“MyMicrowave”.
//This
//with
import
import
import
server program creates and registers two Product objects
the RMIRegistry under the names "MyToaster" and "MyMicrowave"
java.rmi.server.UnicastRemoteObject;
java.rmi.registry.Registry;
java.rmi.registry.LocateRegistry;
public class ProductServer {
public static void main(String args[]) {
try {
// create object
ProductImpl p1 = new ProductImpl("Blackwell Toaster");
// export stub
Product p1Stub = (Product) UnicastRemoteObject.exportObject(p1, 1200);
// create object
ProductImpl p2 = new ProductImpl("Belling Microwave");
// export stub
Product p2Stub = (Product) UnicastRemoteObject.exportObject(p2, 1200);
// obtain handle to registry
2
Registry registry = LocateRegistry.getRegistry();
// bind the name “MyToaster” to the object p1
registry.bind("MyToaster", p1Stub);
// bind the name “MyMicrowave” to the object p2
registry.bind("MyMicrowave", p2Stub);
} catch (Exception e) { }
System.out.println("ProductServer started waiting ...");
} // end main
} // end ProductServer
Step 4 (Start the bootstrap Registry Service)
The Sun RMI library provides a bootstrap registry service to allow the client to locate the server
objects. This registry must be running and can be started with the command (you may go into a
DOS window) and start the registry service with the command: start rmiregistry
Now run the ProductServer program with the command:
java ProductServer
Note. If you developed the program in Netbeans and you are running it via DOS then you need
to go to the “build/classes” directory and run it from there. If necessary set the CLASSPATH to
the current directory. Additionally if you have the “ProductServer” in a package you need to
move to the package level and run it using the format :
<package_name>.ProductServer
Note. It is advisable to start the Registry Service from the same DOS window as server
program.
Step 5 (Develop a client program that looks up server objects and invokes their methods)
Now we write a client program that connects to the registered product objects and calls the
getDescription() method on each of them.
//This client program connects to the server and call the getDescription()
//in remote fashion on both objects.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class ProductClient {
public static void main(String[] args) {
3
String hostName = "localhost"; // default host name
// assign host machine name to connect to
if (args.length != 0) {
if (args[0] != null)
hostName = args[0]; // user specified machine
}
try {
// first locate the registry
Registry registry = LocateRegistry.getRegistry(hostName);
// now locate the stub for each product object
Product c1Stub = (Product) registry.lookup("MyToaster");
Product c2Stub = (Product) registry.lookup("MyMicrowave");
// call the getDescription() method on both objects
System.out.println(c1Stub.getDescription());
System.out.println(c2Stub.getDescription());
} catch (Exception e) {
System.out.println("Error : " + e);
}
System.exit(0);
} // end main
} // end ProductClient
You run this client program (in a DOS window) in the usual way:
java ProductClient
The program simply prints:
I am a Blackwell Toaster. Buy me!
I am a Belling Microwave Buy me!
The output does not seem all that impressive, but consider what goes on behind the scenes
when Java executes the call to the getDescription method.
This is summarised below.
Product c1Stub
getDescription
getDescription
Remote Object Stub
instance
Client
Server that
exported the
remote object
Remote Object
Instance
Server
The client program has a reference to a stub object (e.g. c1Stub) that is obtained from the
registry.lookup method. It calls the getDescription via the stub instance for that object, which
4
results in a network message to the remote object instance on the server side. The remote
instance object invokes the getDescription method on the ProductImpl object located on the
server. That method computes a string result. The string is returned across the network to the
client, received by the remote object stub instance and returned as a result.
Note
In the current version of Java Reflection is employed to create the stubs dynamically at runtime.
Question 2 (Using RMI over the Network)
Now run the above application with the server program on a different machine to the client
program. The only thing that should need to be changed is the URL hostname (i.e. <machine
name> or <machine IP address>) in the client program as now you are connecting to a different
machine.
Note the following files need to be resident on each machine as follows:
server machine:
Product.class // product interface specification
ProductImpl.class // the implementation of the product interface
ProductServer.class // the actual running server
client machine:
Product.class // product interface specification
ProductClient.class // the actual client program
Question 3 – (RMI Another Example)
Develop a new application that allows the server to store the following details about new cars:
Make, Model, Price
Objects representing different people’s favourite cars should now be created and registered
with the server in the registry as follows:
registry.bind(“John_Smiths_Car”, c1Stub);
where cStub is a stub reference to a car object and is the favourite car of John Smith.
The client program should, given the string “John_Smiths_Car”, be able to find it (as the
appropriate registered server object) and call its methods to send back the appropriate car
details, which can then be displayed by the client.
END
5