Distributed Systems Session 4: RPCs (Remote Method Invocation) Java RMI. Christos Kloukinas Dept. of Computing City University London © City University London, Dept. of Computing Distributed Systems / 4 - 1 Outline Motivation and Introduction to Java RMI Conceptual Framework RMI Details Example Implementation Summary © City University London, Dept. of Computing Distributed Systems / 4 - 2 0 Motivation DS require computations running in different address spaces (different hosts) to communicate For basic communication; Java Supports sockets; Sockets API=SEND & RECV CALLS Sockets require Client & Server engage in application level protocols to encode and decode messages for exchange Design of such protocols is cumbersome and error prone Alternative is Remote Procedure Call (RPC) (think of sin(), log(), static methods…) © City University London, Dept. of Computing Distributed Systems / 4 - 3 0.1 RPC RPC abstracts the communication interface to the level of procedure call i.e provides procedural interface to distributed (remote) services Instead of working directly with socket, programmer has illusion of calling a local proc. (transparency) BUT in reality; arguments of the call are packaged and shipped to remote target of call (marshalling) RPC systems encode arguments and return values using an external representation such as XDR © City University London, Dept. of Computing Distributed Systems / 4 - 4 0.2 RPC to RMI RPC does not translate well into distributed object systems (DOS) Communication between program-level objects residing in different address spaces is required To match the semantics of object invocation, DOS require remote method invocation or RMI Here, a local surrogate(stub) object manages invocation on remote object RPC + Object Orientation © City University London, Dept. of Computing Distributed Systems / 4 - 5 0.3 Middleware Layers Application and services RMI and RPC Request-Reply protocol Marshalling and external data Representation Middleware layers TCP and UDP © City University London, Dept. of Computing Distributed Systems / 4 - 6 0.3 Java RMI:The Essence RMI provide you with an object Oriented mechanism to invoke a method on an object that exist somewhere else. Java RMI system assumes the homogeneous environment of the java virtual machines (JVM) therefore it takes advantage of the java platform’s object model whenever possible. © City University London, Dept. of Computing Distributed Systems / 4 - 7 0.4 Java Java is an object-oriented programming language developed by Sun Microsystems that is both compiled and interpreted: A Java compiler creates byte-code, which is interpreted by a virtual machine (VM). Java is portable: Different VMs interpret the byte-code on different hardware and operating system platforms. © City University London, Dept. of Computing Distributed Systems / 4 - 8 0.5 RMI Rationale High-level primitive for object communication (not just UDP datagrams and TCP streams). RMI is tightly integrated with the rest of Java language specification, development environment and the Java VM. Reliance on Java VMs for the resolution of heterogeneity. RMIs can assume a homogeneous representation Java/RMI does not support RMI between Java objects and objects written in another OO language (unless you use the native interface for C/C++) © City University London, Dept. of Computing Distributed Systems / 4 - 9 0.6 Client-Service Before getting into the details, we should examine what an RMI system looks like in comparison to a standard strong-referenced object relationship. In a standard instantiate-and-invoke relationship, there are only the Client and Service objects. They both live in the same virtual machine. Method invocations are made directly on the Service object. © City University London, Dept. of Computing Distributed Systems / 4 - 10 0.7 Client-Service © City University London, Dept. of Computing Distributed Systems / 4 - 11 0.8 RMI In RMI, the Client object does not directly instantiate the Service, BUT gets a reference to its interface through the RMI Naming service. This interface hooks up the client system to the server through a series of layers and proxies until it reaches the actual methods provided by the Service object. © City University London, Dept. of Computing Distributed Systems / 4 - 12 0.9 Remote Method Invocation © City University London, Dept. of Computing Distributed Systems / 4 - 13 1.0 Conceptual Framework: Aspects Architecture. Accessing components from programming languages. Interfaces to lower layers. Component identification. Service invocation styles. Handling of failures. © City University London, Dept. of Computing Distributed Systems / 4 - 14 1.1 System Goals of RMI Seamless integration of objects on different VMs. Support callbacks from servers to applets. Distributed object model for Java » Security, write once run everywhere, multithreaded » Object Orientation Simplicity (learning curve) Safety (maintain Java standards) Flexibility (several invocation mechanisms and various reference semantics, distributed garbage collection) © City University London, Dept. of Computing Distributed Systems / 4 - 15 Distributed Object Application Requirements Locate remote objects » App can register its remote objects with RMI naming facility, the rmiregistry Communicate with remote objects » Details of communication handled by RMI.(Transparency) Load class bytecodes for objects that are passed as parameters or return values » RMI provides class loading © City University London, Dept. of Computing Distributed Systems / 4 - 16 2.0 Remote Method Invocation Overview of RMI architecture. Generation of client/server stubs. RMI interface. Binding. Handling of remote methods. Failures of RMIs. © City University London, Dept. of Computing Distributed Systems / 4 - 17 2.1 RMI Architecture Client Local Call Remote Object Method Server Stub Server Skeleton RMI Interface RMI Interface send receive send Server receive Network © City University London, Dept. of Computing Distributed Systems / 4 - 18 2.2 RMI Components Remote Object Interfaces Client Server Stub Skeleton © City University London, Dept. of Computing Distributed Systems / 4 - 19 2.31 The Remote Object: Remote object is a class that is designed to execute on a server but be treated by the client as if it were local. There are several reasons why you would want to implement a class as a remote object: » the object will run faster, security and proximity to necessary resources than it would on the client. » If the above reasons don’t apply then it’s probably not a good idea to implement a class as a remote object. © City University London, Dept. of Computing Distributed Systems / 4 - 20 2.32 The interface An RMI remote object must extend java.rmi.Remote. When deploying the remote object, a stub is created that implements the same interface. The major purpose of the interface is to provide the template that is used by both the remote object and its stubs. The client never instantiates the remote object itself, and in fact doesn’t even need the class file on its system. © City University London, Dept. of Computing Distributed Systems / 4 - 21 2.33 The Interface: Advantages There are several advantages to using an interface that makes RMI a more robust platform. » Security by preventing decompiling » The interface is significantly smaller than the actual remote object’s class, so the client is lighter in weight. » Maintainability; If changes are made to the underlying remote object, it would need to be propagated to the clients, otherwise serious errors can occur. » From an architectural standpoint, the interface is cleaner. The code in the remote object will never run on the client, and the interface acts appropriately as a contract between the caller and the class performing the work remotely. © City University London, Dept. of Computing Distributed Systems / 4 - 22 2.34 The Client Users of remote objects . Use Naming Class to lookup() objects instead of creating them with the new keyword. However, the remote object is NOT returned, only a stub which happens to implement the same interface of the remote object. Once the client has an object which implements the remote object interface, it can make calls on it as if it was the real object. © City University London, Dept. of Computing Distributed Systems / 4 - 23 2.35 The stub The client needs more than just the interface to call the methods on the remote object. Proxy for the remote object, obtained via naming service Implements all of the methods of its interface. The stub’s major functionality is serializing objects between the client and server over the RMI port, i.e Marshalling and unmarshalling © City University London, Dept. of Computing Distributed Systems / 4 - 24 2.36 The Skeleton On the other side of the connection is a skeleton of the remote object, as well as the remote object itself. When the server starts, it creates an instance of the remote object and waits for invocations. Each time a method is called on the stub from the client, the skeleton object receives a “dispatch” from the server . The Skeleton is responsible for dispatching the call to the actual object implementation. © City University London, Dept. of Computing Distributed Systems / 4 - 25 2.37 The Server RMI server must be present and running on the network. Create with an instance of class that implement remote interface. I.e creates remote objects Can be used to start the RMI naming service. Binds an instance of the remote object to the naming service, giving it an alias in the process. © City University London, Dept. of Computing Distributed Systems / 4 - 26 Implementation Hello World Program © City University London, Dept. of Computing Distributed Systems / 4 - 27 3.0 How to Write RMI Applications 1 Server Client Define your remote interface 2 Implement the interface (.java) 3 javac (.class) Server class (.class) Server skeleton (.class) 4 rmic Client Stub (.class) Run the Stub Compiler uses 8 Implement Client (.java) 9 javac 5 Start RMI registry (.class) 6 Server objects Start 7 Register remote © City University London, Dept. of Computing objects Client 10Start client Distributed Systems / 4 - 28 3.0 How to write an RMI application To write an RMI application proceed as follows: 1) Define a remote interface (Server Services) by extending java.rmi.Remote and have methods throw java.rmi.RemoteException 2) Implement the remote interface. You must provide a Java server class that implements the interface. It must be derived from the class java.rmi.UnicastRemoteObject 3) Compile the server class using javac 4) Run the stub compiler rmic. Run rmic against your (.class) file to generate client stubs and server skeletons for your remote classes. (REMEMBER proxies for marshalling & unmarshalling) 5) Start the RMI registry on your server (call rmiregistry &). The registry retrieves and registers server objects. In contrast to CORBA it is not persistent. 6) Start the server object and register it with the registry using the bind method in java.rmi.Naming 7) Write the client code using java.rmi.Naming to locate the server objects. 8) Compile the client code using javac 9) Start the client © City University London, Dept. of Computing Distributed Systems / 4 - 29 3.1 Implementing RMI Interface for remote object: public interface Hello extends java.rmi.Remote {String sayHello() throws java.rmi.RemoteException; } Implementation of server (declaration): import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloImpl extends UnicastRemoteObject implements Hello { private String name; ... © City University London, Dept. of Computing Distributed Systems / 4 - 30 3.2 Implementing RMI: RMI Core RemoteException superclass for exceptions specific to remote objects thrown by RMI runtime (broken connection, a reference mismatch, e.g.) The Remote interface embraces all remote objects (Does not define methods, but serves to flag remote objects) The RemoteObject class corresponds to Java’s Object class. It implements remote versions of methods such as hashCode, equals, toString The class RemoteServer provides methods for creating and exporting servers (e.g. getClientHost, getLog), I.e. common superclass to server implementations and provides the framework to support a wide range of remote reference semantics. UnicastRemoteObject Your server must either directly inherit or indirectly extend the class and inherit its remote behaviour: implements a special server with the following characteristics: » all references to remote objects are only valid during the life of the process which created the remote object » it requires a TCP connection-based protocol » parameters, invocations etc. are communicated via streams © City University London, Dept. of Computing Distributed Systems / 4 - 31 3.3 Interfaces and Classes Classes Interfaces Remote RemoteObject RemoteServer Activatable © City University London, Dept. of Computing UnicastRemoteObject IOException RemoteException extension implementation Distributed Systems / 4 - 32 3.4 Implementing RMI (Server) Impl. of server (constructor, method, main): public HelloImpl(String s)throws RemoteException {super(); name = s;} public String sayHello() throws RemoteException {return "Hello World!";} public static void main(String args[]){ System.setSecurityManager(new RMISecurityManager()); try { HelloImpl obj = new HelloImpl("HelloServer"); Naming.rebind("//myhost/HelloServer",obj); “localhost” or run Java } catch (Exception e) {…} © City University London, Dept. of Computing like this: java helloSrv `hostname` Distributed Systems / 4 - 33 3.5 Implementing RMI (Server) The class Naming is the bootstrap mechanism for obtaining references to remote objects based on Uniform Resource Locator (URL) syntax. The URL for a remote object is specified using the usual host, port and name: rmi://host:port/name host = host name of registry (defaults to current host) port = port number of registry (defaults to the registry port number) name = name for remote object A registry exists on every node that allows RMI connections to servers on that node. The registry on a particular node contains a transient database that maps names to remote objects. When the node boots, the registry database is empty. The names stored in the registry are pure and are not parsed. A service storing itself in the registry may want to prefix its name of the service by a package name (although not required), to reduce name collisions in the registry. © City University London, Dept. of Computing Distributed Systems / 4 - 34 3.6 Implementing RMI (Client) Remote remoteHello = null; Hello myHello = null; System.setSecurityManager( new RMISecurityManager()); try { remoteHello = Naming.lookup("//myhost/HelloServer"); myHello = (Hello) remoteHello; }… © City University London, Dept. of Computing Distributed Systems / 4 - 35 3.7 Implementing RMI: Summary To summarise the above example: » The server creates the server object and binds it to a name » The client uses lookup to get an object reference and then has to perform a cast to turn a RemoteObject into an object of the proper type © City University London, Dept. of Computing Distributed Systems / 4 - 36 4.0 RMI Interface Used by client or server directly: » Locating servers. » Choosing a transport protocol. » Authentication and security. » Invoking RMIs dynamically. Used by stubs for: » Generating unique message IDs. » Sending messages. » Maintaining message history. © City University London, Dept. of Computing Distributed Systems / 4 - 37 5.0 Binding How to locate an RMI server that can execute a given procedure in a network? Can be done » statically (i.e. at compile-time) or » dynamically (i.e. at run-time). © City University London, Dept. of Computing Distributed Systems / 4 - 38 5.1 Binding A problem that arises is to locate that server in a network which supports the program with the desired remote procedures. This problem is referred to as binding. Binding can be done statically or dynamically. The binding we have seen in the last example was static because the hostname was determined at compile time. Static binding is fairly simple, but seriously limits migration and replication transparency. With dynamic binding the selection of the server is performed at run-time. This can be done in a way that migration and replication transparency is retained. © City University London, Dept. of Computing Distributed Systems / 4 - 39 5.1 Binding Limited support for dynamical server location with the LocateRegistry class to obtain the bootstrap Registry on some host. Usage (minus exception handling): // Server wishes to make itself available to others: SomeSRVC service = ...; // remote object for service Registry registry = LocateRegistry.getRegistry(); registry.bind("I Serve", service); // The client wishes to make requests of the above service: Registry registry = LocateRegistry.getRegistry("foo.services.com"); SomeSRVC service = (SomeSRVC)registry.lookup("I Serve"); service.requestService(...); Programs can be easily migrated from one server to another and be replicated over multiple hosts with full transparency for clients. © City University London, Dept. of Computing Distributed Systems / 4 - 40 6.0 Handling of Remote Methods Call handled synchronously by server. Concurrent RMIs: » serial or » concurrently. Server availability: » continuous or » on-demand. » (RMI & CORBA support both) © City University London, Dept. of Computing Distributed Systems / 4 - 41 7.0 Failures of RMIs Machines or networks can fail at any time. At most once semantics. RMI return value indicates success. Up to the client to avoid maybe semantics! © City University London, Dept. of Computing Distributed Systems / 4 - 42 Summary 1 The client process’s role is to invoke the method on a remote object. The only two things that are necessary for this to happen are the remote interface and stub classes. The server, which “owns” the remote object in its address space, requires all parts of the RMI interchange. When the client wants to invoke a method on a remote object, it is given a surrogate that implements the same interface, the stub. The client gets this stub from the RMI server as a serialized object and reconstitutes it using the local copy of that class. © City University London, Dept. of Computing Distributed Systems / 4 - 43 Summary 2 The third part of the system is the object registry. When you register objects with the registry, clients are able to obtain access to it and invoke its methods. The purpose of the stub on the client is to communicate via serialized objects with the registry on the server. It becomes the proxy for communication back to the server. © City University London, Dept. of Computing Distributed Systems / 4 - 44 Summary The critical parts of a basic RMI system include the client, server, RMI registry, remote object and its matching stub, skeleton and interface. A remote object must have an interface to represent it on the client, since it will actually only exist on the server. A stub which implements the same interface acts as a proxy for the remote object. The server is responsible for making its remote objects available to clients by instantiating and registering them with Naming service. © City University London, Dept. of Computing Distributed Systems / 4 - 45 Critique The Remote Method Invocation (RMI) is a Java system that can be used to easily develop distributed object-based applications. RMI, which makes extensive use of object serialization, can be expressed by the following formula: RMI = Sockets + Object Serialization + Some Utilities The utilities are the RMI registry and the compiler to generate stubs and skeletons. If you are familiar with RMI, you would know that developing distributed object-based applications in RMI is much simpler than using sockets. So why bother with sockets and object serialization then? © City University London, Dept. of Computing Distributed Systems / 4 - 46 Critique • The advantages of RMI in comparison with sockets are: • Simplicity: RMI is much easier to work with than sockets • No protocol design: unlike sockets, when working with RMI there is no need to worry about designing a protocol between the client and server -- a process that is error-prone. • The simplicity of RMI, however, comes at the expense of the network. • There is a communication overhead involved when using RMI and that is due to the RMI registry and client stubs or proxies that make remote invocations transparent. For each RMI remote object there is a need for a proxy, which slows the performance down. © City University London, Dept. of Computing Distributed Systems / 4 - 47 Online Resources & Reading Chapter 4 of Course textbook Chapter 5 of Coulouris & Dollimore Examples at //web.archive.org/web/20031220223738/http://www.churchillobje cts.com/c/11086.html Tutorials at //engronline.ee.memphis.edu/advjava/online.htm short tutorial at //www.eg.bucknell.edu/~cs379/DistributedSystems/rmi_tut.html Next Session: CORBA & COMPARISON WITH RMI © City University London, Dept. of Computing Distributed Systems / 4 - 48