250 likes | 383 Views
Advanced Programming. Rabie A. Ramadan Lecture 4. A Simple Use of Java Remote Method Invocation (RMI). Consider the following program organization:. If the network is the computer, we ought to be able to put the two classes on different computers. method call. AnotherClass. SomeClass.
E N D
Advanced Programming Rabie A. Ramadan Lecture 4
Consider the following program organization: If the network is the computer, we ought to be able to put the two classes on different computers method call AnotherClass SomeClass returned object computer 1 computer 2 “The network is the computer”* • RMI is one technology that makes this possible
CORBA (Common Object Request Broker Architecture) has long been king CORBA supports object transmission between virtually any languages Objects have to be described in IDL (Interface Definition Language), which looks a lot like C++ data definitions CORBA is complex and flaky Microsoft supported CORBA, then COM, now .NET RMI is purely Java-specific Java to Java communications only As a result, RMI is much simpler than CORBA RMI and other technologies
Java makes RMI (Remote Method Invocation) fairly easy, but there are some extra steps To send a message to a remote “server object,” The “client object” has to find the object Do this by looking it up in a registry The client object then has to marshal the parameters (prepare them for transmission) Java requires Serializable parameters The server object has to unmarshal its parameters, do its computation, and marshal its response The client object has to unmarshal the response Much of this is done for you by special software What is needed for RMI?
A remote object is an object on another computer The client object is the object making the request (sending a message to the other object) The server object is the object receiving the request As usual, “client” and “server” can easily trade roles (each can make requests of the other) The rmiregistry is a special server that looks up objects by name Hopefully, the name is unique! rmicis a special compiler for creating stub (client) and skeleton (server) classes Terminology
For RMI, you need to be running three processes The Client The Server The Object Registry, rmiregistry, which is like a DNS service for objects You also need TCP/IP active Processes
Interfaces define behavior Classes define implementationTherefore, In order to use a remote object, the client must know its behavior (interface), but does not need to know its implementation (class) In order to provide an object, the server must know both its interface (behavior) and its class (implementation) In short, The interface must be available to both client and server The class should only be on the server Interfaces
A Remote class is one whose instances can be accessed remotely On the computer where it is defined, instances of this class can be accessed just like any other object On other computers, the remote object can be accessed via object handles A Serializable class is one whose instances can be marshaled (turned into a linear sequence of bits) Serializable objects can be transmitted from one computer to another Classes
If an object is to be serialized: The class must be declared as public The class must implement Serializable The class must have a no-argument constructor All fields of the class must be serializable: either primitive types or serializable objects Conditions for serializability
In RMI, a common remote interfaceis the minimum amount of information that must be shared in advance between “client” and “server” machines. It defines a high-level “protocol” through which the machines will communicate. A remote interface is a normal Java interface, which must extent the marker interface java.rmi.Remote. Corollaries: because the visible parts of a remote object are defined through a Java interface, constructors, static methods and non-constant fields are not remotely accessible (because Java interfaces can’t contain such things). All methods in a remote interface must be declared to throw the java.rmi.RemoteException exception. The Remote Interface
A file MessageWriter.javacontains the interface definition: import java.rmi.* ; public interface MessageWriter extends Remote { void writeMessage(String s) throws RemoteException ; } This interface defines a single remote method, writeMessage(). A Simple Example
The interface java.rmi.Remoteis a marker interface. It declaresnomethods or fields; however, extending it tells the RMI system to treat the interface concerned as a remote interface. In particular we will see that the rmic compiler generates extra code for classes that implement remote interfaces. This code allows their methods to be called remotely. java.rmi.Remote
Requiring all remote methods be declared to throw RemoteException was a philosophical choice by the designers of RMI. RMI makes remote invocations look syntacticallylike local invocation. In practice, though, it cannot be defend from problems unique to distributed computing—unexpected failure of the network or remote machine. Forcing the programmer to handle remote exceptions helps to encourage thinking about how these partial failuresshould be dealt with. See the influential essay: “A Note on Distributed Computing” by Waldo et al, republished in The Jini Specification: http://java.sun.com/docs/books/jini java.rmi.RemoteException
A remote object is an instance of a class that implements a remote interface. Most often this class also extends the library class java.rmi.server.UnicastRemoteObject. This class includes a constructor that exports the object to the RMI system when it is created, thus making the object visible to the outside world. Usually you will not have to deal with this class explicitly—your remote object classes just have to extend it. One fairly common convention is to name the class of the remote object after the name of the remote interface it implements, but append “Impl” to the end. The Remote Object
The file MessageWriterImpl.java contains the class declaration: import java.rmi.* ; import java.rmi.server.* ; public class MessageWriterImplextends UnicastRemoteObject implements MessageWriter { public MessageWriterImpl() throws RemoteException { } public void writeMessage(String s) throws RemoteException { System.out.println(s) ; } } ARemote Object Implementation Class
To compile classes that implement Remote, you must use the rmiccompiler. The reasons will be discussed later. For example: rabie$ rmicMessageWriterImpl Compiling the Remote Object Class
We have completed the Java files for the remote object class itself, but we still need the actual client and server programs that usethis class. In general there are some pieces of administrivia one has to deal with—publishing class files and installing security managers. We initially make the simplifying assumption that both client and server have copies of all class files for MessageWriter. Then “publishing class files” is not an issue, and we also don’t need a security manager, because all codeis “local”, and therefore trusted. Client and Server Programs
We assume the file HelloServer.javacontains the class declaration: import java.rmi.* ; public class HelloServer { public static void main(String [] args) throws Exception { MessageWriter server = new MessageWriterImpl() ; Naming.rebind(“messageservice”, server) ; } } AServer Program
This program does two things: It creates a remote object with local name server. It publishes a remote reference to that object with external name “MessageWriter”. The call to Naming.rebind() places a reference to serverin an RMI registryrunning on the local host (i.e., the host where the HelloServer program is run). Client programs can obtain a reference to the remote object by looking it up in this registry. Remarks
We assume the file HelloClient.java contains the class declaration: import java.rmi.* ; public class HelloClient { public static void main(String [] args) throws Exception { MessageWriter server = (MessageWriter) Naming.lookup( “rmi://rabieramadan.org/messageservice”) ; server.writeMessage(“Hello, other world”) ; } } A Client Program
Again the program does two things: It looks up a reference to a remote object with external name “MessageWriter”, and stores the returned reference with local name server. Finally (!), it invokes the remote method, writeMessage(), on server. The call to Naming.lookup() searches ina remoteRMI registry. Its argument is a URL,with protocol tag “rmi”. This example assumes the remote object lives on the host “rabieramadan.org”, and has been registered in the default RMI registry (which happens to listen on port 1099) on that machine. Remarks
Compile HelloServerand HelloClient on their respective hosts, e.g.: sirah$ javacHelloServer merlot$ javacHelloClient Either ensure client and server share the current directory, or copy all files with names of the form MessageWriter * .class to the client’s current directory. Compiling and Running the Example