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.