Rmi
Rmi
Bob Tarr
Distributed Computing
l
Distributed Computing involves the design and implementation of applications as a set of cooperating software entities (processes, threads, objects) that are distributed across a network of machines Advantages to Distributed Computing
Performance Scalability Resource Sharing Fault Tolerance Latency Synchronization Partial Failure
Bob Tarr
Client-Server Programming
l
Client-Server Model
Client - entity that makes a request for a service Server - entity that responds to a request and provides a service
The predominant networking protocol in use today is the Internet Protocol (IP). The main API for writing client-server programs using IP is the Berkeley socket API.
Bob Tarr
Client-Server Programming
l
Dealing with all of the details of the socket library calls can be tedious. (See, for example, Stevens Unix Network Programming.) The java.net package provides classes to abstract away many of the details of socket-level programming, making it simple to write client-server applications
Bob Tarr
Client Example
import java.net.*; import java.io.*; /** * Client Program. * Connects to a server which converts text to uppercase. * Server responds on port 2345. * Server host specified on command line: java Client server_host */ public class Client { public static void main(String args[]) { Socket s; String host; int port = 2345; DataInputStream is; DataInputStream ui; PrintStream os; String theLine; Remote Method Invocation Design Patterns In Java Bob Tarr
5
host = args[0]; try { s = new Socket(host, port); is = new DataInputStream(s.getInputStream()); os = new PrintStream(s.getOutputStream()); ui = new DataInputStream(System.in); System.out.println("Enter Data"); while(true) { theLine = ui.readLine(); if (theLine.equals("end")) break; os.println(theLine); System.out.println(is.readLine()); }
Design Patterns In Java
Bob Tarr
Bob Tarr
Server Example
import java.net.*; import java.io.*; /** * Server Program. * Converts incoming text to uppercase and sends converted * text back to client. * Accepts connection requests on port 2345. */ public class Server { public static void main(String args[]) { ServerSocket theServer; Socket con; PrintStream ps; DataInputStream dis; String input; int port = 2345; boolean flag = true; Remote Method Invocation Design Patterns In Java
8
Bob Tarr
Bob Tarr
Bob Tarr
Remote Procedures
l
In the previous example, the client communicated to the server over a socket connection using a protocol known to both parties But both the client and server had to be aware of the socket level details Wouldnt it be nice if even these details were abstracted away and the request to the server looked like a local procedure call from the viewpoint of the client? Thats the idea behind a Remote Procedure Call (RPC), a technology introduced in the late 1970s Two RPC specifications:
SUNs Open Network Computing (ONC) RPC OSFs Distributed Computing Environment (DCE) RPC
Remote Method Invocation
11
Bob Tarr
But RPC is not object-oriented. In the OO world, wed like to have distributed objects and remote method calls. While there are many Distributed Object Technologies available today, three are widely available:
RMI CORBA SOAP Developed by SUN Available as part of the core Java API Java-centric Object interfaces defined as Java interfaces Uses object serialization
Remote Method Invocation
12
Bob Tarr
Developed by the Object Management Group (OMG) Language and platform independent Object interfaces defined in an Interface Definition Language (IDL) An Object Request Broker (ORB) facilitates the client-server request/response action ORBs communicate via a binary protocol called the Internet Inter-ORB Protocol (IIOP) Simple Object Access Protocol XML-Based Developed from an earlier spec called XML-RPC Standardized by the W3C Many implementations available
Remote Method Invocation
13
Bob Tarr
SOAP
RMI
l l
Provides a distributed object capability for Java applications Allows a Java method to obtain a reference to a remote object and invoke methods of the remote object nearly as easily as if the remote object existed locally The remote object can be in another JVM on the same host or on different hosts across the network Uses object serialization to marshal and unmarshal method arguments Supports the dynamic downloading of required class files across the network
Bob Tarr
RMI Application
l
RMI Application
Bob Tarr
RMI uses stub and skeleton objects to provide the connection between the client and the remote object A stub is a proxy for a remote object which is responsible for forwarding method invocations from the client to the server where the actual remote object implementation resides A client's reference to a remote object, therefore, is actually a reference to a local stub. The client has a local copy of the stub object. A skeleton is a server-side object which contains a method that dispatches calls to the actual remote object implementation A remote object has an associated local skeleton object to dispatch remote calls to it
Remote Method Invocation
16
Bob Tarr
Note: Java 2 (JDK1.2) does not require an explicit skeleton class. The skeleton object is automatically provided on the server side. A method can get a reference to a remote object
by looking up the remote object in some directory service. RMI provides a simple directory service called the RMI registry for this purpose. by receiving the remote object reference as a method argument or return value
Bob Tarr
An object becomes remote-enabled by implementing a remote interface, which has these characteristics:
A remote interface extends the interface java.rmi.Remote Each method of the interface declares java.rmi.RemoteException in its throws clause, in addition to any application-specific exceptions 1. Design and implement the components of your distributed application
Define the remote interface(s) Implement the remote object(s) Implement the client(s)
2. Compile sources and generate stubs (and skeletons) 3. Make required classes network accessible 4. Run the application
Remote Method Invocation
18
Bob Tarr
RMI Example 1
l l
The classic Hello, World Example using RMI! First, define the desired remote interface:
import java.rmi.*; /** * Hello Interface. */ public interface IHello extends Remote { public String sayHello() throws RemoteException; }
A class that implements this remote interface can be used as a remote object. Clients can remotely invoke the sayHello() method which will return the string Hello, World to the client.
Remote Method Invocation
19
Bob Tarr
Next, provide an implementation of the remote object Well implement the remote object as a server The remote object server implementation should:
Declare the remote interfaces being implemented Define the constructor for the remote object Provide an implementation for each remote method in the remote interfaces Create and install a security manager Create one or more instances of a remote object Register at least one of the remote objects with the RMI remote object registry (or some other naming service), for bootstrapping purposes
To make things simple, our remote object implementation will extend java.rmi.server.UnicastRemoteObject. This class provides for the exporting of a remote object by listening for incoming calls to the remote object on an anonymous port.
Remote Method Invocation
20
Bob Tarr
Bob Tarr
Bob Tarr
Bob Tarr
Bob Tarr
We next use the rmic utility to generate the required stub and skeleton classes:
rmic HelloServer
Bob Tarr
Our next step would be to make the class files network accessible. For the moment, lets assume that all these class files are available locally to both the client and the server via their CLASSPATH. That way we do not have to worry about dynamic class downloading over the network. Well see in the next example how to properly handle that situation. The files that the client must have in its CLASSPATH are:
IHello.class HelloClient.class HelloServer_Stub.class
The files that the server must have in its CLASSPATH are:
IHello.class HelloServer.class HelloServer_Stub.class HelloServer_Skel.class (Not needed in Java 2)
Bob Tarr
If you run this example in Java 2, you need a security policy file that allows the downloading of class files Here is an example policy file that allows anything!
grant { permission java.security.AllPermission; };
Heres a policy file that allows the program to connect to or accept connections from any host on ports greater than 1024 and to connect to any host on port 80 (the default HTTP port):
grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept"; permission java.net.SocketPermission "*:80", "connect"; };
Bob Tarr
On the client:
RMI Example 2
l l
The server in this example implements a generic compute engine The idea is that a client has some CPU-intensive job to do, but does not have the horsepower to do it. So the client encapsulates the task to be done as an object and sends it over to a server to be executed. The compute engine on the server runs the job and returns the results to the client. The compute engine on the server is totally generic and can execute any kind of task requested by the client This example illustrates one of our Design Patterns. Which one??
Bob Tarr
Bob Tarr
Heres the generic task interface we'll need for this example:
package compute; import java.io.Serializable; /** * Task Interface. */ public interface Task extends Serializable { Object execute(); }
Bob Tarr
Bob Tarr
public Object executeTask(Task t) { return t.execute(); } public static void main(String[] args) { // Install a security manager! if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } // Create the remote object. // Register the remote object as "Compute". String name = "rmi://serverhost/Compute";
Bob Tarr
Bob Tarr
Here's a client which asks the server to compute the value of pi:
package client; import java.rmi.*; import java.math.*; import compute.*; /** * Client that asks the Generic Compute Server to compute pi. * The first command-line argument is the server hostname. * The second command-line argument is the number of required * digits after the decimal point for the computation. */ public class ComputePi {
Bob Tarr
Bob Tarr
// Ask the server to perform the computation. BigDecimal pi = (BigDecimal)(comp.executeTask(task)); System.out.println(pi); } catch (Exception e) { System.err.println("ComputePi exception: " + e.getMessage()); e.printStackTrace(); } } }
Bob Tarr
Bob Tarr
Bob Tarr
Now we are ready to build the application. First, build a jar file of the interface classes:
cd /home/waldo/src javac compute/Compute.java javac compute/Task.java jar cvf compute.jar compute/*.class
Let's say that, ann, the developer of the ComputeEngine class, has placed ComputeEngine.java in the /home/ann/src/engine directory and is deploying the class files for clients to use in a subdirectory of her public_html directory, /home/ann/public_html/classes. Let's assume that the compute.jar file is located in the directory /home/ann/public_html/classes. To compile the ComputeEngine class, your class path must include the compute.jar file and the source directory itself.
Remote Method Invocation
40
Bob Tarr
setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar cd /home/ann/src javac engine/ComputeEngine.java rmic -d . engine.ComputeEngine mkdir /home/ann/public_html/classes/engine cp engine/ComputeEngine*.class /home/ann/public_html/classes/engine
The -d option tells the rmic compiler to place the generated class files, ComputeEngine_Stub and ComputeEngine_Skel, in the directory /home/ann/src/engine. You also need to make the stubs and skeletons network accessible, so you must copy the stub and skeleton class to the public_html/classes area.
Bob Tarr
Since the ComputeEngine's stub implements the Compute interface, which refers to the Task interface, you need to make these two interface class files network accessible along with the stub. So, the final step is to unpack the compute.jar file in the directory /home/ann/public_html/classes to make the Compute and Task interfaces available for downloading.
Bob Tarr
Let's assume that user jones has created the client code in the directory /home/jones/src/client and will deploy the Pi class (so that it can be downloaded to the compute engine) in the network-accessible directory /home/jones/public_html/classes (also available via some web servers as http://host/~jones/classes/). The two client-side classes are contained in the files Pi.java and ComputePi.java in the client subdirectory. In order to build the client code, you need the compute.jar file that contains the Compute and Task interfaces that the client uses. Let's say that the compute.jar file is located in /home/jones/public_html/classes. The client classes can be built as follows:
Bob Tarr
Only the Pi class needs to be placed in the directory public_html/classes/client (the client directory is created by javac if it does not exist). That is because only the Pi class needs to be available for downloading to the compute engine's virtual machine.
Bob Tarr
Why do we make sure that rmiregistry has no CLASSPATH set when we start it??
If the rmiregistry can find the stub classes in its CLASSPATH, it will not remember that the stub class can be loaded from the server's code base, as specified by the java.rmi.server.codebase property. Therefore, the rmiregistry will not tell the client the proper codebase when the client downloads the stub object from the rmiregistry. Consequently, the client will not be able to download the stub class.
Bob Tarr
When you start the compute engine, you need to specify, using the java.rmi.server.codebase property, where the server's classes will be made available. In this example, the server-side classes to be made available for downloading are the ComputeEngine's stub and the Compute and Task interfaces, available in ann's public_html/classes directory.
Bob Tarr
Bob Tarr