310 likes | 421 Views
Distributed Applications using RMI. Recall Sockets. Good Efficient, well-understood Language/platform independent Easy to customize for security and compression Less Good Not very abstract “Stream” data model isn’t very OO
E N D
Recall Sockets • Good • Efficient, well-understood • Language/platform independent • Easy to customize for security and compression • Less Good • Not very abstract • “Stream” data model isn’t very OO • Relies on application-level protocol being defined (and implemented)
RMI Application Overview • Comprised of two separate programs: • Server • Client • Server • Creates some remote objects • makes references to them accessible • waits for clients to invoke methods on these remote objects • Client • gets a remote reference to one or more remote objects in the server • invokes methods on them • Sometimes referred to as a distributed object application.
Distributed Object Application • Need to • Locate remote objects • Communicate with remote objects • Load class bytecodes for objects that are passed around registry RMI RMI Server URL Protocol Client RMI URL Protocol URL Protocol Web Server Web Server
RMI – Remote Method Invocation • Distribute the objects across different machines to take advantage of hardware and dedicated software • Developers build network service and install it on specified machines • Users request an instance of a class using URL syntax • Users use objects as though it were a regular, local object • Network connections happened automatically behind the scenes • Java “Serialization” lets you pass complex data structures over the network without writing code to parse and reconstruct them
RMI – Remote Method Invocation • RMI is Java’s RPC mechanism • Language specific (Java) • Object oriented (full objects as parameters) • Mobile behavior (move class implementation from client to server, and server to client) • Safe & Secure • A way to send messages to objects over the network • Built on top of sockets • Friendly and easy to use for Java programmers • A framework for building distributed applications
RMI Terminology • A remote objectis one whose methods can be invoked from another JVM, potentially on a different host • Remote method invocation (RMI) is the action of invoking method of a remote interface on a remote object //Local method invocation example HashTable table = new HashTable(); table.put(“theKey", "theValue!"); //Remote method invocation example (incomplete) PasswdDb db = (PasswdDb)Naming.lookup(“//myhost/obj”); db.put("theKey", “theValue!");
Java RMI Architecture • Servers extend RemoteObject and implement remote interfaces • Any serializable object can be sent as a parameter or returned as a response • The RMI compiler generates client stubs (proxies) and server skeletons (dispatchers)
RMI Operations • Stub Operations • Package identifier of remote object • Package method identifier • Marshal parameters • Send package to server skeleton • Skeleton Operations • Unmarshall parameters • Calls return value or exceptions • Marshall method return • Send package to the client stub
RMI Details • RMI Interfaces and Classes public interface Remote {} public abstract class RemoteObject implements Remote, Serializable { protected RemoteObject(); protected RemoteObject(RemoteRef newref); public int hashCode(); public boolean equals(Object obj); public String toString(); } Remote RemoteObject ServerObject Unicast RemoteObject IOException RemoteException
Example: Phone number lookup • The example runs a server which stores a list of names and phone numbers. • Like all the server programs it must be running prior to any clients. • The difference with RMI, is that clients, once connected to the server, can make requests of the server using methods available at the server end rather than relying on raw sockets. • This removes the load of designing protocols and socket handling by the programmer, allowing the server to be treated like any other object. • The handling of requests is done through stub code at the client end and skeleton at the server end.
Example: Phone number lookup • To create a distributed application follow these steps: • Design and implement the components of your distributed application. • Defining the remote interfaces • Implementing the remote objects • Implementing the client • Compile sources and generate stubs. • Make classes network accessible. • Start the application.
Defining the remote interfaces • A remote interface specifies the methods that can be invoked remotely by a client import java.rmi.*; public interface PhoneBook extends Remote { String getEntry(String name) throws RemoteException; }
Implementing the remote objects import java.rmi.*; import java.util.*; import java.rmi.server.UnicastRemoteObject; public class PhoneBookImpl extends UnicastRemoteObject implements PhoneBook { Hashtable numbers = new Hashtable(); public PhoneBookImpl() throws RemoteException { super(); numbers.put("Sibtain", "990-3-2702"); numbers.put("Sayed", "990-3-2181"); } public String getEntry(String name) throws RemoteException { return numbers.get(name) == null ? "UNKNOWN“ : (String)numbers.get(name); } }
Creating Phone Book Server public class PhoneBookServer { public static void main(String[] args) { System.setSecurityManager( new RMISecurityManager()); try { PhoneBookImpl obj = new PhoneBookImpl(); Naming.rebind(“rmi://phonebook", obj); System.out.println( "Phonebook bound in registry"); } catch (Exception e) { System.out.println( "PhonebookImpl err: " + e.getMessage()); e.printStackTrace(); } } }
Creating Phone Book Client import java.rmi.*; public class PhoneBookClient { static BufferedReader console; static { try { Console = new BufferedReader( new InputStreamReader(System.in)); } catch (Exception) {} } private PhoneBook phoneBook; public PhoneBookClient(String host) throws Exception { phoneBook = (PhoneBook) Naming.lookup(“rmi://” + host + “/phonebook"); } public String getNumbre(String name) throws RemoteException { return phoneBook.getEntry(name); }
Creating Phone Book Client public static void main(String[] args) throws Exception { try { PhoneBookClient client = new PhoneBookClient(args[0]); String name = null, phone = null; while ((name=console.readLine()) != null) { phone = client.getNumber(name); System.out.println(“Phone number: “ + phone); } } catch (RemoteException ex) { ex.printStackTrace(); } catch (NotBoundException ex) { ex.printStackTrace(); } catch (MalFormedURLException ex) { ex.printStackTrace(); } } }
rmiregistry Naming.lookup Naming.rebind getNumber(String) PhoneBookServer getEntry
Compile sources and generate stubs. • Compile the client and server % javac PhoneBook.java % javac PhoneBookServer.java % javac PhoneBookImpl.java % javac PhoneBookClient.java • Generate the client stub and server skeleton % rmic PhoneBookImpl • Output: PhoneBookImpl_Stub.class, PhoneBookImpl_Skeleton.class • The client machine needs PhoneBook.class, PhoneBookClient.class, PhonebookImpl_Stub.class • The server machine needs PhoneBook.class, PhoneBookImpl.class, PhoneBookServer.class, PhoneBookImpl_Skeleton.class
Make classes network accessible • Stub files need to be placed on a HTTP Server for downloading • In Java 2, the RMI 1.2 protocol does not require the skeleton • Client must install an RMISecurityManager to load the RMI classes remotely System.setSecurityManager( new RMISecurityManager()); • Client requires a policy file to connect to the registry and HTTP server
Running the Application • Start the RMI Registry server> rmiregistry & • The ‘&’ is used to put the registry process in background on Unix • You can also specify the port number; default is 1099 • Start the server server> java PhoneBookServer & • Start the client client> java PhoneBookClient
Policy File for the Client grant { // rmihost – RMI registry and server // webhost – HTTP server for the Stub classes Permission java.net.SocketPermission “rmihost:1024-65535”, “connect”; Permission java.net.SocketPermission “webhost:80”, “connect” } • Need to grant permission to ports 1024-65535 on the server • The server communicates with the rmiregistry (and client) on a randomly selected ports • Alternatively, can set policies in java.policy located in $JAVA_HOME/lib/security/
Enterprise RMI, Remote Message Example import java.rmi.*; import java.io.*; import java.net.*; public class PhoneBookClient { public static void main(String[] args) { try { System.setSecurityManager(new RMISecurityManager()); String host = args.length > 0 ? args[0] : “localhost”; PhoneBook remoteObj = (PhoneBook)Naming.lookup( “rmi://”+ host + “/phonebook”); … } catch (RemoteException ex) { ex.printStackTrace(); } catch (NotBoundException ex) { ex.printStackTrace(); } catch (MalFormedURLException ex) { ex.printStackTrace(); } } }
Compiling & Running • Compile client and server prompt> javac PhoneBookCleint.java prompt> javac PhoneBookImpl.java • Generate the client Stub and server skeleton prompt> rmic –v1.2 PhonebookImpl • Place the files on correct machines:
Compiling & Running • Start the HTTP server • Place the PhoneBookImpl_Stub.class on an HTTP server • Start the RMI registry server> /somedirectory/rmiregistry & • Start the Server server>java –Djava.rmi.server.codebase=http://webhost/rmi PhoneBookImpl • Server must be on the same host as rmiregistry
Compiling & Running • Start the client client>java -Djava.security.policy=rmiclient.policy PhoneBookClient rmihost • rmihost is server in which rmiregistry was started
Summary • RMI is pure java based protocol for communicating with remote objects • Register (bind) and look-up remote objects in a registry • Java 2 no longer requires the skeleton class needed with the RMI 1.1 protocol • Enterprise RMI configuration requires a RMI Security Manager and client policy file for permission
Java RMI Resources • Sun Microsystems, Java RMI documentations http://www.javasoft.com • The Java language specifications (online book) http://java.sun.com/docs/books/jls/ • The Java Tutorial (online book) http://java.sun.com/docs/books/tutorial/