CS4273: Distributed System Technologies and Programming I Lecture 12: Java RMI (Remote Method Invocation) Client-Server Programming without RMI (RPC) Server Client Main () { …… read(file,buf,n); …... } Main { Loop on: recv req r = read(file, n); pack rep send rep to clnt } read(fd,buf,n) { make a socket to svr prepare a req socket send req recv rep copy data to mybuf } stub read(file,n) { …… get data from disk …… } write(file,data,n) { ……. } stub 2 Remote Method Invocation (RMI) Stub objects are auto-generated by “rmic” from interface definition Interface implmentation rmic rmic Client RMI Stub Object Server Stub Object Server Object 3 An Example of RMI An interface interface Product extends Remote { String getDescription () throws RemoteException; String placeOrder () throws RemoteException; int getOrderNo () throws RemoteException; } N.B. every rmi method must throw exceptions, due to the un-reliability of RMI. A service routine public class ProductImpl extends UnicastRemoteObject implements Product { public ProductImpl (String pd) throws RemoteException { descript = pd; } public String getDescription () { return “ProductDescipt:” + descript + “. ”; } private String descript; ………. } A client RMI call …… Product p = Naming.lookup(url-name); String descript = p.getDescription (); System.out.println(descript); …… 4 Inheritance Graph of Interface and Remote servers Object Remote RemoteObject RemoteStub extends RemoteServer implements UnicastRemoteObject RMI interface definition interface implement object 5 Naming Conventions for RMI classes and Files Interface def file Interface impl file no suffix (e.g. Product) Impl suffix (e.g. ProductImpl) Server program file Client program file Stub program file Server suffix (e.g. ProductServer) Client suffix (e.g. ProductClient) _Stub suffix (e.g. ProductImpl_Stub) 6 Client-Server Binding in RMI • • • • An RMI registration server (rmiregistry) on a site is responsible for locating any appl servers on that site. This rmiregistry should run on the server site before any appl servers start. An appl server needs to register itself to rmiregistry on the same site when it is created. A client looks up an appl server from rmiregistry on that site by specifying the server’s URL-addr rmiregistry lookup (rmi://svr-site/svr-name). A naming class client rebind java.rmi.server.Naming RMI server provides an interface for servers to reg / de-reg and for clients to look up servers. 7 An Example of RMI A simple interface implementation program import java.rmi.*; import java.rmi.server.*; // file: rmi/svr/ProductImpl.java public class ProductImpl extends UnicastRemoteObject implements Product { private String descript; public ProductImpl (String pd) throws RemoteException { descript = pd; } public String getDescription () { return "ProductDescript" + descript + "."; } } A server program // creates an impl obj and registers it public class ProductSvr {// file: rmi/svr/ProductSvr.java public static void main (String args[]) { try { ProductImpl p1 = new ProductImpl (“Jia’s Warehouse"); Naming.rebind ("warehouse", p1); // register svr by name } catch (Exception e) { System.out.println("Error:" +e);} } } 8 Compile Server Program We have the following files in server’s directory: Product.java // interface file ProductImpl.java // interface implementation file ProductSvr.java // server program file 1. Compile the interface file: javac Product.java It can be skipped. When compiling ProductImpl.java, it is auto-compiled. 2. Compile the server implementation: javac ProductImpl.java 3. Generate stub class using RMIC: rmic ProductImpl It generates file ProductImpl_Stub.class (for both client and server). N.B. ProductImpl java must be compiled before using “rmic”. 4. Compile the server program: javac ProductSvr.java N.B. the server links procedures in ProductImpl_Stub at run-time. 9 A Simple Client Program // file: ~java/rmi/clnt/ProductClnt.java //usage: java ProductClnt server-hostname import java.rmi.*; import java.rmi.server.*; public class ProductClnt { public static void main (String args[]) { String url = "rmi://"+args[0]; try { Product p1 = (Product) Naming.lookup (url + "/warehouse"); System.out.println(p1.getDescription()); System.out.println(p1.placeOrder()); System.out.println("OrderNo: " + p1.getOrderNo()); } catch (Exception e) { System.out.println("Error:" +e);} } } 10 Build Client Program 1. Copy interface file Product.java to local directory. 2. Copy the client stub file ProductImpl_Stub.class (generated by rmic) to the local directory. 3. Compile the client source code: javac ProductClnt.java • • when compiling ProductClnt.java, it automatically compiles the interface Product.java if it has not been compiled yet. The compiler locates the interface Product.java by naming conventions. client calls stub procedures in ProductImpl_Stub.class at run-time. It is in a separate class file, without linking to the client at compilation time. 11 Run the Example of RMI • Start RMI registry program on the server site: rmiregistry & • Start the server program on the server site: java ProductSvr & • Start the client program on the client site: java ProductClnt args 12 Naming class for client-server Binding RMI uses class “java.rmi.server.Naming” for client-server binding functions, which includes: • static Remote lookup (String url) returns the remote object for the URL • static void bind(String name, Remote obj) binds name to the remote object obj • static void rebind(String name, Remote obj) binds name to remote obj & replaces any existing one • static void unbind(String name) unbinds the name • static String[] list(String url) returns an array of strings of urls registered at the registry server. 13 View Database of RMI Registration Server // file: ~java/rmi/showBinding.java import java.rmi.*; import java.rmi.server.*; public class showBindings { public static void main ( String[] args) { try { String [] bindings = Naming.list(""); for (int i = 0; i < bindings.length; i++) System.out.println(bindings[i]); } catch(Exception e) {System.out.println("Error"+e);} } } 14 Summary of Programming with RMI On Server Site 1. write an interface file. 2. write the interface implementation program, which implements all methods in the interface. 3. write a server program, which initializes a server-impl object and registers the server object with the registry. 4. compile all the source files on server side. 5. generate stub class by using rmic. 15 Summary of Programming with RMI (Cont.) On Client Site 6. copy the interface file and the generated stub class file to the local directory (from the server site). 7. write a client program that uses rmi. 8. compile the client program. Run the Client & Server 9. run the registry server on server site. 10. run server and client on server and client sites respectively. 16 Applets Using RMI server client applet RMI HTTP CORBA IIOP CGI server server 17 Programming Applets using RMI The server (and rmiregistry server) must run on the Web server, bcs applets can only communicate with their home server!!! 1. Copy the interface file (Product.java) and the stub class file (ProductImpl_Stub.class) to the local directory. 2. Write applet "ProductApplet.java" and compile it. 3. Run "rmiregistry" and server "ProductSvr" on the Web Server site. 4. Run applet in Web Browser. N.B. No need to change the server program rmiregistry when moving a client to an applet. lookup applet rebind RMI server 18 An Example of RMI Applet Program // file: java/rmi/applet/ProductApplet.java import java.rmi.*; import java.rmi.server.*; import java.applet.Applet; public class ProductApplet extends JApplet { private String message = "Initializing…"; public void init() { String url = "rmi://" + getCodeBase().getHost(); // web-site !!! try { Product p1 = (Product) Naming.lookup (url + "warehouse"); message = p1.getDescription(); // rmi repaint(); } catch (Exception e) { System.out.println("Error:" +e);} } public synchronized void paint(Graphics g) { g.drawString(message, 5, 50); } } 19