Download JAVA - RMI - PoliformaT
Document related concepts
no text concepts found
Transcript
Diseño Y Aplicaciones de Sistemas Distribuidos Invocación de métodos remotos en Java: JAVA - RMI Joan Vila DISCA / UPV Departament d’Informàtica de Sistemes i Computadors Universitat Politècnica de València JAVA-RMI JAVA-RMI: Java Remote Method Invocation – Sistema de invocación de métodos remotos que (a diferencia de CORBA) asume un entorno homogéneo de Máquina Virtual Java. – Proporciona un modelo de objetos distribuidos similar al de Java, integrándolo en el lenguaje de manera natural. En este sentido permite: Invocar métodos de interfaces remotas Pasar una referencia a un objeto remoto en una invocación (local o remota) Soportar callbacks de servidores a Applets. – Presenta algunas limitaciones respecto al modelo de objetos de Java Los clientes siempre interaccionan con las interfaces, nunca con las implementaciones. Los argumentos no remotos de la invocaciones y los resultados siempre se pasan por copia, nunca por referencia. Los objetos remotos se pasan por referencia no por copia Existen excepciones adicionales que pueden ocurrir durante una RMI. Procesamiento distribuido en Java © Joan Vila 51 Java-RMI Arquitectura de JAVA-RMI Server object Client object Skeletons Stubs Objects references level Transport level Procesamiento distribuido en Java © Joan Vila 52 Java-RMI Concurrencia en Java-RMI Cuando varios clientes invocan métodos concurrentemente sobre un objeto servidor son, en general, ejecutados por diferentes hilos. – Invocaciones de clientes diferentes son siempre ejecutadas en hilos diferentes. – Invocaciones del mismo cliente pueden no ser ejecutadas por hilos diferentes dependiendo de la implementación de la máquina virtual. Client object Server object Client object Procesamiento distribuido en Java © Joan Vila 53 Java-RMI Generación de stubs y skeletons – Generados automáticamente por un preprocesador llamado rmic – Se generan a partir del fichero de implementación del objeto servidor (no a partir de su interfaz) Servicio de nombres – Los nombres no son transparentes a la ubicación: //host/objectName – Se accede a través de la clase java.rmi.Naming Cliente: Remote ref = Naming.lookup("//" +host + "/NombreObjeto"); Servidor: Naming.rebind("//" + myURL + "/NombreObjeto", obj); – En todo host donde residan servicios, debe ejecutarse un servidor de nombres, llamado rmiregistry. Este servidor sólo mantiene entradas de servicios locales. Procesamiento distribuido en Java © Joan Vila 54 Java-RMI Client Server Interface javac lookup Client rebind rmi registry Stub Server javac Server Skeleton rmic Procesamiento distribuido en Java © Joan Vila 55 Java-RMI Objetos como argumentos en invocaciones – Los objetos se pueden pasar por valor o por referencia en las invocaciones a métodos remotos. Paso por valor: los objetos locales se pasan por valor (migration) Pass by reference: los objetos remotos se pasan por referencia – Serializacion de objetos: Java-RMI dispone de un sofisticado mecanismo de serialización que permite convertir objetos en secuencias de bytes aptos de ser enviados por un OutputStream como,p.e., un socket. – Los objetos pasados por valor deben implementar la interfaz Serializable. class aClass implements java.io.Serializable; aclass X; ObjectOutputStream ObjectOutputStream(sock.getOutputStream()); Procesamiento distribuido en Java os.writeObject(x); os = new © Joan Vila 56 Java-RMI Clases e interfaces RMI Defined in packages java.rmi and java.rmi.server Interfaces Classes Remote RemoteObject IOException RemoteServer RemoteException extends UnicastRemoteObject Procesamiento distribuido en Java Implements © Joan Vila 57 Java-RMI Clases e interfaces RMI – Todos los objetos servidores RMI deben declarar un interfaz. Este interfaz debe ser subclase de java.rmi.remote. Obliga a propagar excepciones de comunicación en la declaración de métodos. – La clase java.rmi.server.RemoteObject proporciona la semántica de la clase Object para objetos remotos: igualdad, conversión a String – La clase java.rmi.server.RemoteServer métodos para crear y exportar objetos. proporciona – La clase UnicastRemoteObject es una especialización de la anterior que proporciona soporte para invocar objetos (no replicados). Procesamiento distribuido en Java © Joan Vila 58 Un ejemplo en Java-RMI (i) Un ejemplo simple – La aplicación echo La interfaz del servicio de a red ote e H em R public interface EchoIntRMI extends java.rmi.Remote { String echo(String aString) throws java.rmi.RemoteException; } Procesamiento distribuido en Java Ex c es epc pe ion cíf ica es s © Joan Vila 59 Un ejemplo en Java-RMI (i) El cliente de echo Java siempre resuelve las referencias remotas en tiempo de ejecución (late binding). Interfaz objeto remoto } public interface EchoIntRMI extends java.rmi.Remote { ... ... Binding ing Narrow Remote ref = Naming.lookup("//" +host + "/EchoObject"); EchoIntRMI eo = (EchoIntRMI) ref; eo.echo(“hola”); Procesamiento distribuido en Java ces a f r inte e d o álog t a C © Joan Vila 60 Un ejemplo en Java-RMI (i) package RMI.Echo; import java.io.*; import java.rmi.*; El cliente de echo EchoRMI.java public class EchoRMI { public static void main(String[] args) { if (args.length<1) { System.out.println("Usage: Echo <host>"); System.exit(1); } try { EchoIntRMI obj = (EchoIntRMI) Naming.lookup("//"+args[0]+"/EchoObject"); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String input,output; while ((input = stdIn.readLine()) != null) { output = obj.echo(input); System.out.println("echo: " + output); } } catch (Exception e) { System.out.println("EchoRMI exception: " + e.getMessage()); } } } Procesamiento distribuido en Java © Joan Vila 61 Un ejemplo en Java-RMI (i) El objeto echo (i) EchoObjectRMI.java package RMI.Echo; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; import java.net.InetAddress; public class EchoObjectRMI extends UnicastRemoteObject implements EchoIntRMI { public EchoObjectRMI() throws RemoteException { super(); } public String echo(String aString) throws RemoteException { return aString; } Procesamiento distribuido en Java Implementa el interfaz Constructor Proporcionar implementacion a los métodos © Joan Vila 62 Un ejemplo en Java-RMI (i) El objeto echo (i): método main public static void main(String args[]) { System.setSecurityManager(new RMISecurityManager()); String myURL="localhost"; try { EchoObjectRMI obj = new EchoObjectRMI(); myURL=InetAddress.getLocalHost().getHostName(); Naming.rebind("//" + myURL + "/EchoObject", obj); } catch (Exception e) { System.out.println("EchoObject error: " + e.getMessage()) Instanciar un Gestor Seguridad Instanciar la clase Registrar objeto en el servicio de nombres } } } Procesamiento distribuido en Java © Joan Vila 63 JAVA-RMI “Migración” de objetos – La aplicación ComputeEngine Enviar Tarea ComputePi Cliente Compute Engine Devolver resultado Procesamiento distribuido en Java © Joan Vila 64 Un ejemplo en Java-RMI (ii) “Migración” de objetos Definición de interfaces (i): el objeto servidor package compute; Compute.java import java.rmi.Remote; import java.rmi.RemoteException; public interface Compute extends Remote { Object executeTask(Task t) throws RemoteException; } Procesamiento distribuido en Java Hereda de Remote © Joan Vila 65 Un ejemplo en Java-RMI (ii) “Migración” de objetos Definición de interfaces (ii): la tarea a migrar package compute; Task.java import java.io.Serializable; public interface Task extends Serializable { Object execute(); } Procesamiento distribuido en Java Hereda de Serializable © Joan Vila 66 Un ejemplo en Java-RMI (ii) “Migración” de objetos El objeto servidor (i) package engine; ComputeEngine.java import java.rmi.*; import java.rmi.server.*; import compute.*; public class ComputeEngine extends UnicastRemoteObject implements Compute { public ComputeEngine() throws RemoteException { super(); } a de d e r e H bject O e t o stRem a c i n U Implementa Compute public Object executeTask(Task t) { return t.execute(); } Procesamiento distribuido en Java © Joan Vila 67 Un ejemplo en Java-RMI (ii) “Migración” de objetos El objeto servidor (ii): el método main ComputeEngine.java ... public class ComputeEngine extends UnicastRemoteObject implements Compute { ar ... stal er n i r e anag a e public static void main(String[] args) { r C M rity u c if (System.getSecurityManager() == null) { Se System.setSecurityManager(new RMISecurityManager()); } String name = "//localhost/Compute"; try { Compute engine = new ComputeEngine(); Registrar objeto en servidor de Naming.rebind(name, engine); nombres System.out.println("ComputeEngine bound"); } catch (Exception e) { Procesamiento distribuido en Java © Joan Vila 68 Un ejemplo en Java-RMI (ii) “Migración” de objetos El cliente (i): el método main package client; ComputePi.java import java.rmi.*; import java.math.*; import compute.*; public class ComputePi { lar a t s n r e i anager a public static void main(String args[]) { e r C M rity u c if (System.getSecurityManager() == null) { Se System.setSecurityManager(new RMISecurityManager()); } ... Procesamiento distribuido en Java © Joan Vila 69 Un ejemplo en Java-RMI (ii) “Migración” de objetos El cliente (ii): el método main package client; ... ComputeEngine.java to e j public class ComputePi { ob r de r public static void main(String args[]) { ca ido s s v Bu ser bre ... en nom try { String name = "//" + args[0] + "/Compute"; Compute comp = (Compute) Naming.lookup(name); Instancia Pi task = new Pi(Integer.parseInt(args[1])); de task BigDecimal pi = (BigDecimal) (comp.executeTask(task)); System.out.println(pi); Invoca r obje } catch (Exception e) { to System.err.println("ComputePi exception: " + e.getMessage()); e.printStackTrace(); } } } Procesamiento distribuido en Java © Joan Vila 70 Un ejemplo en Java-RMI (ii) “Migración” de objetos El cliente (ii): la tarea Pi package client; import compute.*; import java.math.*; Pi.java public static BigDecimal calculatePi(int digits) { ... } public class Pi implements Task { } ... Imp lem private int digits; enta de public Pi(int digits) { this.digits = digits; } public Object execute() { return calculatePi(digits); } Procesamiento distribuido en Java Tas k Implementa el método execute © Joan Vila 71