Download Desarrollo de aplicaciones con RMI
Document related concepts
no text concepts found
Transcript
PROGRAMACION DISTRIBUIDA Desarrollo de aplicaciones con RMI Héctor Pérez 2 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException <<abstract class>> RemoteObject <<exceptionClass>> RemoteException <<abstract class>> RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject 3 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException <<abstract class>> RemoteObject <<exceptionClass>> RemoteException <<abstract class>> Interrupción generada por algún fallo en los mecanismos internos y opacos de la invocación remota RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject 4 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Clase java.rmi.RemoteException ! Es la clase raíz de las excepciones que puede lanzar el middleware RMI durante una invocación de un método remoto ! Es lanzada cuando la invocación de un método remoto falla por alguna razón propia del mecanismo RMI (pero no errores en el código de negocio), tales como: " fallos en la comunicación " fallos en los procesos de serialización o recomposición de los parámetros o resultados " errores de protocolo ! Es una excepción chequeada, no una RuntimeException " su lanzamiento debe ser declarado en todos los métodos remotos " su gestión es chequeada por el compilador 5 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Clases especializadas de RemoteException ! AccessException ! Es lanzada para indicar que el cliente no tiene permiso para invocar el método ! ActivateFailedException ! Es lanzada por el runtime de RMI cuando la activación falla durante la invocación remota de un objeto activable ! ! ! ! ! ConnectException, ConnectIOException, ExportException, InvalidTransactionException, MarshalException, ! ! ! ! ! ! ! ! ! ! ! ! NoSuchObjectException, ServerError, ServerException, ServerRuntimeException, SkeletonMismatchException, SkeletonNotFoundException, StubNotFoundException, TransactionRequiredException, TransactionRolledbackException, UnexpectedException, UnknownHostException, UnmarshalException 6 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException Identificar las interfaces cuyos métodos pueden ser invocados desde una máquina virtual remota. <<abstract class>> RemoteObject <<exceptionClass>> RemoteException <<abstract class>> RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject 7 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaz java.rmi.Remote ! La interfaz Remote es la base que debe ser extendida por cualquier interfaz que se declara como remota " No declara ningún método ! Para que una interfaz sea remota se requiere: " Debe extender directa o indirectamente a la interfaz java.rmi.Remote " Todos los métodos declarados en ella deben satisfacer los siguientes requisitos: ! Los métodos remotos deben incluir la declaración de la excepción java.rmi.RemoteException ! Un objeto remoto declarado como parámetro o valor de retorno de los métodos remotos debe ser declarado por la referencia a su correspondiente interfaz remota, no a la clase que implemente esa interfaz. ! Una interfaz remota puede extender otras interfaces no remotas siempre que los métodos definidos en ellas satisfagan los criterios de los métodos remotos 8 RCSD: José M. Drake y Héctor Pérez Ejemplos de interfaces remotas // Ejemplo de interfaz remota import java.rmi.Remote; import java.rmi.RemoteException; public interface Hola extends Remote { String di_hola() throws RemoteException; } // Ejemplo de interfaz remota derivada de otra interfaz no remota public interface Alfa { public final String okay=“Soy una constante”; public Object foo(Object object) throws java.rmi.RemoteException; public void bar() throws java.rmi.RemoteException; public int baz() throws java.rmi.RemoteException; } public interface Beta extends Alfa, java.rmi.Remote { public void ping() throws java.rmi.RemoteException; } 11/05/2015 9 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException Identificar las interfaces cuyos métodos pueden ser invocados desde una máquina virtual remota. <<abstract class>> RemoteObject <<exceptionClass>> RemoteException <<abstract class>> RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject 10 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Clase abstracta RemoteObject ! Representa la clase raíz de los objetos remotos. ! Redefine algunos métodos de Object para aportar la semántica de los objetos remotos: boolean equals (Object obj) RemoteRef getRef () static Remote toStub (Remote obj) Compares two remote objects for equality Returns the remote reference for the remote object Returns the stub for the remote object. This operation is only valid after exporting the object int hashCode () Returns a hashcode a remote object String toString () Returns a String that represents the value of this remote object 11 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException <<abstract class>> RemoteObject <<exceptionClass>> RemoteException Añade el framework para ser referenciado con semántica de servidor remoto. <<abstract class>> RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject 12 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Clases abstracta RemoteServer ! Aporta a RemoteObject el referencias a objetos remotos framework de las static String getClientHost () Returns a string representation of the client host for the remote method invocation being processed in the current thread static PrintStream getLog () Returns stream for the RMI call log static void setLog (OutputStream out) Log RMI calls to the output stream out 13 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException <<abstract class>> RemoteObject <<exceptionClass>> RemoteException <<abstract class>> RemoteSever <<abstract class>> <<class>> Activatable UnicastRemoteObject Corresponde a un objeto remoto que ha sido registrado en el middleware rmi, y por tanto tiene asignado una referencia remota o stub. 14 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Clase UnicastRemoteObject ! Define un objeto remoto concreto cuya referencia sólo es válida mientras que el thread del server está vivo (alive) ! Constructores: protected UnicastRemoteObject () Creates and exports a new UnicastRemoteObject object using an anonymous port protected UnicastRemoteObject (int port) Creates and exports a new UnicastRemoteObject object using the supplied port ! Métodos: Object clone() Returns a clone of the remote object that is distinct from the original static Remote exportObject (Remote obj, int port) Exports the remote object to make it available to receive incoming calls static boolean unexportObject (Remote obj, boolean force) Removes the remote object from the RMI runtime 15 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Implementación de un servidor remoto ! La clase servidor debe implementar al menos una interfaz remota " y cualquier número de interfaces no remotas " puede definir nuevos métodos públicos (no remotos) ! Requiere exportar el objeto remoto 1. la clase servidor extiende UnicastRemoteObject y los objetos remotos son exportados automáticamente 2. la clase servidor utiliza los métodos estáticos de UnicastRemoteObject ! El objeto remoto debe ser thread-safe 16 RCSD: José M. Drake y Héctor Pérez 11/05/2015 HolaMundo: Implementación del servidor import java.rmi.RemoteException; import java.rmi.registry.*; import java.rmi.server.UnicastRemoteObject; public class ServidorHola implements Hola { public ServidorHola() {} public String di_hola() { return "Hola, Mundo!"; } // Constructor // Implementación del método remoto public static void main(String args[]) { try { //Instancia del servidor ServidorHola server = new ServidorHola(); // El servidor se registra en el RMI como un objeto remoto y se obtiene su referencia remota Hola ServidorHolaRef = (Hola) UnicastRemoteObject.exportObject(server, 0); // El servidor se registra en el registry con un nombre (“Servidor_Hola”) Registry registry = … System.err.println("ServidorHola instalado"); // Servidor instalado con éxito } catch (Exception e) { System.err.println("Server exception: " + e.toString()) } } } 17 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Marshalling en RMI ! La serialización depende del tipo de dato: " Los tipos de datos primitivos son pasados por valor directamente " los objetos locales son pasados por valor ! se transmite el objeto completo (información, comportamiento, etc) ! deben implementar la interfaz java.io.Serializable, o se lanzará NotSerializableException public class Position implements Serializable {…} ! La mayoría de las clases de la API de Java son serializables (p.ej., un HashMap puede ser serializado si los objetos que almacena lo son) " los objetos remotos son pasados por referencia 18 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Localización de objetos remotos (1/3) ! RMI proporciona una aplicación denominada rmiregistry que actúa como servidor de nombres rmiregistry <puerto_escucha> ! El registry puede restringir el acceso a algunos de sus métodos " p.ej., aquellos métodos que modifiquen el registro deben ser invocados localmente " si se deniega el acceso a algún método, se lanza AccessException localmente, que se transforma en una ServerException para un cliente remoto ! El registry debe tener acceso a la clase del objeto a registrar " si están en el mismo nodo, podemos utilizar el CLASSPATH 19 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Localización de objetos remotos (2/3) ! La interfaz registry define los métodos que ofrece un objeto de tipo registry para almacenar y recuperar objetos remotos mediante un identificador void bind (String name, Remote obj) Binds a remote reference to the specified name in this registry. void rebind (String name, Remote obj) Replaces the binding for the specified name in this registry with the supplied remote reference. void unbind (String name) Removes the binding for the specified name in this registry. String[] list () Returns an array of the names bound in this registry. Remote lookup (String name) Returns the remote reference bound to the specified name in the registry. 20 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Localización de objetos remotos (3/3) ! La clase LocateRegistry se utiliza para obtener la referencia (obtener el stub) de un registro sobre un procesador determinado static Registry createRegistry (int port) Creates and exports a Registry instance on the local host that accepts requests on the port. static Registry getRegistry () Returns a reference to the the remote object Registry for the local host on the port 1099. static Registry getRegistry (int port) Returns a reference to the the remote object Registry for the local host on the port. static Registry getRegistry (String host) Returns a reference to the remote object Registry on the specified host on the port 1099. static Registry getRegistry (String host, int port) Returns a reference to the remote object Registry on the specified host and port. 21 RCSD: José M. Drake y Héctor Pérez 11/05/2015 HolaMundo: Registro del servidor import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; public class ServidorHola implements Hola { public ServidorHola() {} public String di_hola() { return "Hola, Mundo!"; } // Constructor // Implementación del método remoto public static void main(String args[]) { try { ServidorHola server = new ServidorHola(); //Instancia del servidor // El servidor se registra en el RMI como un objeto remoto y se obtiene su referencia remota Hola ServidorHolaRef = (Hola) UnicastRemoteObject.exportObject(server, 0); // El servidor se registra en el registry con un nombre (“Servidor_Hola”) Registry registry = LocateRegistry.getRegistry(); registry.rebind (“Servidor_Hola", ServidorHolaRef ); System.err.println("ServidorHola instalado"); // Servidor instalado con éxito } catch (Exception e) { System.err.println("Server exception: " + e.getMessage()) } } } 22 RCSD: José M. Drake y Héctor Pérez 11/05/2015 HolaMundo: Consulta del registro por el cliente import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; public class ClienteHola { private ClienteHola() {} // Constructor public static void main(String[] args) { // El primer parámetro es el host de Registry String elHost=null; // Si no hay parámetro, usa el local if (args.length >= 1) elHost= args[0]; try { // Se localiza el servidor en el registro por su nombre “Servidor_Hola” · Registry registry = LocateRegistry.getRegistry(elHost); Hola elServidor = (Hola) registry.lookup("Servidor_Hola"); String respuesta = elServidor.di_hola(); // Se invoca el servicio remoto System.out.println("Respuesta: " + respuesta); } catch (Exception e) { System.err.println("Excepción del cliente: " + e.getMessage());} } } 23 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Carga dinámica de clases (1/2) ! La invocación de un objeto remoto requiere disponer de su referencia remota: " puede recibirse como parámetro o valor de retorno, obtenerse a través del registry o incluso cargarse dinámicamente ! La propiedad codebase de la JVM permite especificar las URLs dónde pueden descargarse las clases " las propiedades proporcionan información sobre la JVM y su entorno " la información asociada al codebase forma parte del stub java -Djava.rmi.server.codebase=http://istr.unican.es/tmp/clases.jar main ! La carga dinámica de clases puede tener múltiples propósitos 24 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Carga dinámica de clases (2/2) import java.rmi.Remote; import java.rmi.RemoteException; public interface Hola_v2 extends Hola { String di_buenos_dias() throws RemoteException; // Nueva funcionalidad } public class ClienteHola { private ClienteHola() {} // Cliente para Hola_v1 public static void main(String[] args) { // El primer parámetro es el host de Registry String elHost=null; // Si no hay parámetro, usa el local if (args.length >= 1) elHost= args[0]; try { // Se localiza el servidor en el registro por su nombre “Servidor_Hola” · Registry registry = LocateRegistry.getRegistry(elHost); Hola elServidor = (Hola) registry.lookup("Servidor_Hola"); // Cast sobre Hola_v2 … } } 25 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Gestor de seguridad (1/2) ! Si nuestra interfaz contiene métodos que requieren como argumentos o retornan clases distintas del API de Java, resulta necesario implementar un gestor de seguridad ! Hay que activar el gestor de seguridad de Java: if (System.getSecurityManager()==null) System.setSecurityManager(new SecurityManager()); ! Podemos modificar la política de seguridad de Java con un fichero de permisos " Por ejemplo, el fichero puede incluir: grant{ permission java.security.AllPermission; }; " El fichero se especifica a través de una propiedad de la JVM -Djava.security.policy=grantFilePath " O desde el código: System.setProperty("java.security.policy", <url>); 26 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Servicios RMI: Gestor de seguridad (2/2) ! El fichero de permisos controla quién puede acceder y qué operaciones puede realizar en el nodo " Algunos permisos permiten utilizar caracteres especiales como (comodín recursivo) y * (comodín local) " SocketPermission permite configurar las operaciones resolve, connect, listen y accept grant { permission java.net.SocketPermission "*.unican.es:1024-“, "accept, connect“;}; FilePermission permite configurar las operaciones read, write, execute y delete grant { permission java.io.FilePermission “/home/alumnos/temp/*" , "read, write";}; ! Se puede utilizar -Djava.security.debug=access para saber qué operaciones se están denegando 27 RCSD: José M. Drake y Héctor Pérez 11/05/2015 Interfaces y clases raíces definidas en RMI <<class>> Object <<interface>> <<exceptionClass>> Remote IOException Identificar las interfaces cuyos métodos pueden ser invocados desde una máquina virtual remota. Añade el framework para ser referenciado con semántica de servidor remoto. <<abstract class>> RemoteObject Identificar las interfaces cuyos métodos pueden ser invocados desde una máquina virtual remota. <<abstract class>> RemoteException Interrupción generada por algún fallo en los mecanismos internos y opacos de la invocación remota RemoteSever Proporciona los recursos para poder ser almacenada persistentemente en disco y ser activada remotamente por el rmi. <<exceptionClass>> <<abstract class>> <<class>> Activatable UnicastRemoteObject Corresponde a un objeto remoto que ha sido registrado en el middleware rmi, y por tanto tiene asignado una referencia remota o stub.