Java Remote Method Invocation ============================= 1) What is a distributed application? 1.1) What are the components of a distributed application? - locator - clients - servers 1.2) Which are different ways to implement a distributed system? 2) Has anyone ever heard of RPC? - Xerox's courier: 1981 - Birrew et al's network objects: 1994 (Modula-3) * Java Remote Method Invocation is the act of an object c calling a method on another object s, that is not in the same virtual machine as c. 3) Let's try to schematize this with a diagram? client: Server: s.ms() o.ms(); A A | | V V Stub(proxy) <-------------> Skeleton(adapter) s.ms() private RemoveObj o connect listem send send recv recv 4) What is missing so that we can have RMI? - Name server - Dynamic class loading. 5) Let's design a cloud computing system? 5.1) What is that? 5.2) How to implement it? 5.3) What kind of applications we would like to send to the clouds? 5.4) Which interfaces are involved in this problem? 5.5) How to represent this as a diagram? Client Compute |------- executeTask(Task t) -------->| | | |<----------------- T -------------------| * Here is the code of the Task interface: package compute; public interface Task { T execute(); } * and below goes compute: package compute; import java.rmi.Remote; import java.rmi.RemoteException; public interface Compute extends Remote { T executeTask(Task t) throws RemoteException; } 6) What is special about this interface? 7) The method executeTask is meant to be executed remotely. It returns an instance of T. What we must know about T? * T can be a remote object, or an object that implements the Serializable interface. 8) What would happen if the JVM where c:Compute is running does not have access to an object that is required by the task? * A remote object is an object that implements a remote interface. There is a number of things that a remote object must do: - Create and install a security manager. - Create and export one or more remote objects. - Register itself in the distributed naming service. 9) How would it be the implementation of the Compute interface? package engine; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import compute.Compute; import compute.Task; public class ComputeEngine implements Compute { public ComputeEngine() { super(); } public T executeTask(Task t) { return t.execute(); } public static void main(String[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Compute"; Compute engine = new ComputeEngine(); Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0); Registry registry = LocateRegistry.getRegistry(); registry.rebind(name, stub); System.out.println("ComputeEngine bound"); } catch (Exception e) { System.err.println("ComputeEngine exception:"); e.printStackTrace(); } } } 10) Any redundancy in this Code? What about the constructor? 11) Different programming languages implement different strategies to pass parameters. Can you give examples? 11.1) How are parameters passed in Java? 11.2) Why this is not good to pass remote objects? * Local objects are passed by copy, using object serialization. * Remote objects are passed by reference. A remote object reference is a stub, which is a client-side proxy that implements the complete set of remote interfaces that the remote object implements. 12) Let's take a look into what the main method is doing. First of all, what are the two initial lines? 12.1) Why is security necessary? - To download classes, for instance. 13) What is this exportObject method good for? - To initialize the network stuff. 13.1) What is the second integer argument? - The inform a port to listen. 14) The method exportObject throws an exception: RemoteException. What could go wrong? - The port is taken - No network 15) How can clients find the remote object? 15.1) What is the class java.rmi.registry.LocateRegistry good for? 15.2) How does the binding work? 16) When is the program above going to finish running? 16.1) When is the remote object engine going to be reclaimed by the garbage collector? 17) We need now some clients to our remote application. Which kinds of clients does it make sense to build? 18) What is this example client doing? package client; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.math.BigDecimal; import compute.Compute; public class ComputePi { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { String name = "Compute"; Registry registry = LocateRegistry.getRegistry(args[0]); Compute comp = (Compute) registry.lookup(name); Pi task = new Pi(Integer.parseInt(args[1])); BigDecimal pi = comp.executeTask(task); System.out.println(pi); } catch (Exception e) { System.err.println("ComputePi exception:"); e.printStackTrace(); } } } 18.1) What is this lookup method all about? 18.2) Which port does it read from? 19) Now, this task thing: how can we compute the value of pi? 20) What is this "private static final long serialVersionUID = 227L;" in the Pi.java file? 21) How does the server virtual machine have access to the Pi class? * The essential point is: the Pi.java object is implemented without any hint that it will be used remotely. * Compiling with dynamic class loading - follow these steps if you need DCL: * 22) How can we build a jar file out of the compute package? javac compute/Compute.java compute/Task.java jar cvf compute.jar compute/*.class mv compute.jar ~/public-html/classes/ 23) How to compile the ComputeEngine class? cd ../engine javac -cp ~/public-html/classes/compute.jar ComputeEngine.java 24) How to compile the client? javac -cp ~/public-html/classes/compute.jar Pi.java mkdir ~/public-html/classes/client cp Pi.class ~/public-html/classes/client/ * In case you don't need DCL, just do the following: * * Java RMI relies on a name server. To start the name server, type: $> rmiregistry 25) What happens when you do this? * We need a policy descriptor, which will describe which privileges we have: grant codeBase "file:/home/vip/fpereira/Documents/DCC_Classes/52/lessons/lesson21/unico" { permission java.security.AllPermission; }; The policy descritor is a file, e.g: server.policy, which is located in the same directory where you have either the client or the server application. This file must contain the path to the directory where execution will take place. * To start the server, type: $> java -Djava.security.policy=server.policy ComputeEngine * To start the client, type: java -Djava.security.policy=server.policy ComputePi tigre.dcc.ufmg.br 10