• No se han encontrado resultados

RMI. Ingeniería del Software II Curso 2007/2008. Sergio Ilarri Artigas

N/A
N/A
Protected

Academic year: 2021

Share "RMI. Ingeniería del Software II Curso 2007/2008. Sergio Ilarri Artigas"

Copied!
59
0
0

Texto completo

(1)

RMI

Ingeniería del Software II Curso 2007/2008

Sergio Ilarri Artigas [email protected]

(2)

Índice

„ Introducción

„

Stubs

y

Skeletons

(

rmic

)

„ Objetos Remotos y Objetos Serializables:

„ Interface Remoto: ejemplo „ Objeto Remoto: ejemplo

„ El Servicio de Nombres (

rmiregistry

) „ Ejemplo de Servidor y de Cliente

„ Intercambio de Referencias Remotas

(3)

Reflexión

¿Tienen los

sockets

alguna pega?

(4)

Introducción

„

En lugar de trabajar directamente con

sockets

, RMI:

„ Permite invocar métodos de objetos

remotos de forma transparente

„ Asume un entorno Java homogéneo

„ Por tanto, podemos beneficiarnos de su

(5)

¿Cómo podríamos invocar objetos

remotos de forma transparente?

Que un objeto local se haga pasar por el objeto

remoto y se encargue él de las comunicaciones

(6)

¿Cómo podríamos programar un

objeto que trate las invocaciones

remotas como si fueran locales?

Que otro objeto local se encargue de las

comunicaciones y delegue en él la ejecución de

las operaciones invocadas

(7)

Stubs

y

Skeletons

Stub Skeleton

Red

Decodifica (unmarshalling/deserialization) los datos, invoca al método del servidor, devuelve resultados o excepciones

Invoca método implementado por el objeto servidor

Cliente Servidor

Codifica (marshalling/serialization) y envía los datos y la invocación

por la red

(8)

Stub

„ Cada clase de objetos remota tiene una clase

stub

asociada que implementa el

interface

remoto:

„ Usada por el cliente en sustitución de la clase

remota

„ Las invocaciones remotas del cliente en realidad

se dirigen al stub

„ En la implementación de cada operación, se envía

un mensaje con los parámetros de invocación serializados a la máquina virtual que ejecuta el objeto remoto

(9)

¿A qué patrón suena esto?

Un

stub

es un

Proxy

Reflexión

(10)

Skeleton

„

Clase usada por el servidor:

„ Recibe los mensajes remotos

„

Deserializa

los parámetros de invocación „ Invoca el método del objeto que

implementa el

interface

remoto

„

Serializa

los resultados y los devuelve al

(11)

Reflexión

¿A qué patrón suena esto?

(12)

Objetos Remotos y

Serializables

„

Objetos remotos:

„ Reciben invocaciones remotas

„ Se pasan por referencia (remota) „ Tienen localización fija

„ Implementa un

interface remoto

„

Objetos serializables:

„ Encapsulan datos „ Se pasan por valor

„ Pueden transferirse a otra máquina virtual

Todo argumento o valor de retorno en RMI implements Remote implements Serializable

(13)

Interface

Remoto (I)

„ Define el protocolo de alto nivel entre cliente

y servidor

„ Es un interface Java normal pero que

extiende

java.rmi.Remote

„ En él el servidor declara los métodos

disponibles remotamente para los clientes

„ Todos esos métodos deben lanzar

java.rmi.RemoteException

„ Todos los argumentos y resultados deben ser

(14)

Ejemplo de

Interface

Remoto

import java.rmi.* ;

public interface MessageWriter extends Remote {

void writeMessage(String s) throws RemoteException ; }

(15)

¿Cómo conseguimos evitar que un

método de un objeto remoto pueda

ser invocado remotamente?

No definiéndolo en un

interface

que extienda

java.rmi.Remote

(16)

¿Puede un cliente acceder

remotamente a métodos estáticos?

No, pues no pueden definirse en un

interface

Java (igual que los atributos no constantes)

(17)

public interface ClockWithMillis extends Clock {

... }

No aparece extends Remote... Pero os digo que es un interface remoto... ¿Cómo es posible?

Será que

Clock

sí extiende el

interface Remote

(18)

Interface Remoto (II)

„

El interface

java.rmi.Remote

:

„ No declara ni métodos ni atributos „ Su único propósito es “marcar” que

cualquier interface que lo extienda debe ser tratado por el sistema RMI como un interface remoto

„ El compilador de RMI

rmic

genera clases

stub

y

skeleton

para aquellas clases que implementan interfaces remotos

(19)

public interface Clock {

public long getTime(); }

public interface ClockWithMillis extends Clock, Remote {...}

¿Por qué el ejemplo anterior no compilaría?

Porque

getTime

no declara que lanza

RemoteException

(20)

RemoteException

„ Todos los métodos remotos deben declarar

que pueden lanzar

java.rmi.RemoteException

(superclase de todas la excepciones RMI)

„ Invocaciones remotas:

„ Sintácticamente como las locales

„ Pero pueden producirse fallos en la red, al

serializar o deserializar argumentos, etc.

„ Se obliga al programador a tratar esos fallos

„ Las excepciones en el objeto “servidor” también se

encapsulan y se propagan al “cliente”

Exception chaining

(21)

El Objeto Remoto

„ Instancia de una clase que implementa un

interface remoto

„ Esta clase debe extender normalmente

java.rmi.server.UnicastRemoteObject

„ Constructor (sin argumentos) que exporta el

objeto al sistema RMI

„ El programador normalmente no usa esta clase

explícitamente, simplemente se extiende

„ Convención de nombrado:

<nombreInterfaceRemoto>Impl

El constructor de la clase implementada debe lanzar RemoteException

(22)

Ejemplo de Objeto Remoto

import java.rmi.* ;

import java.rmi.server.* ;

public class MessageWriterImpl extends UnicastRemoteObject implements MessageWriter { public MessageWriterImpl() throws RemoteException {

}

public void writeMessage(String s) throws RemoteException { System.out.println(s) ;

} }

(23)

Compilador de RMI

„

Utilizado para “compilar” clases que

implementan

Remote

(clases de

implementación remotas)

„

rmic

(parte del JDK):

„

rmic ClassName

genera las clases:

„ ClassName_Stub (implementa el interface remoto)

„ ClassName_Skel (no con la versión del protocolo stub 1.2)

„

Con -keep

, mantiene el código fuente

(24)

Un “cliente” de una máquina desea

comunicar con un “servidor”.

¿Cómo sabe dónde está?

-La localización se codifica en el código cliente

-El usuario indica la localización

-Nivel de indirección: servicio de nombres

(25)

Servicio de Nombres (I)

„

Funciona como un listín telefónico:

„ Permite al cliente saber dónde se está

ejecutando el objeto con el que desea contactar

„ Objetivo: independencia de localización java.rmi.Naming

(26)

Servicio de Nombres (II)

En java.rmi.Naming tenemos los siguientes métodos estáticos:

public static void bind(String name, Remote object) public static void rebind(String name, Remote object) public static void unbind(String name)

public static String[] list(String name) public static Remote lookup(String name)

Un parámetro nombre (name) es una URL con el formato:

//registryHost:port/logical_name

Por defecto, el host (opcional) es localhost Por defecto, el puerto (opcional) es 1099

(27)

Servicio de Nombres (III)

Se abre un socket con el

registry

(servidor de nombres)

Se serializa el

stub

que implementa el

objeto remoto

Se liga dicho

stub

con un nombre

bind(), rebind(), unbind()

El servidor asocia un nombre lógico al objeto

(28)

Servicio de Nombres (IV)

„

lookup()

: devuelve el

stub

ligado al

nombre dado

„

list()

: devuelve los nombres de todos

los objetos remotos registrados en ese

servidor de nombres

list(), lookup()

(29)

Servicio de Nombres (V)

„

java.rmi.Naming

es una clase de utilidad que

registra/contacta objetos a partir de una URL:

„ A partir de la URL, determina un objeto remoto

registry, que implementa el interface

java.rmi.registry.Registry, utilizando la clase de utilidad java.rmi.registry.LocateRegistry

„ Y ahora registra o contacta el objeto invocando un

método de instancia, análogo al estático usado en java.rmi.Naming, sobre el objeto registry

(30)

Servicio de Nombres (VI)

Código del cliente Objeto remoto Cliente Servidor Registry Almacena referencia Solicita referencia

(31)

Servicio de Nombres (VII)

„ Por tanto, distinguimos 3 pasos:

1. Se llama a un método estático de Naming con

una cierta URL

2. Se analiza la URL y la información de máquina y

puerto se utiliza para, a través de la clase

LocateRegistry, obtenerse el stub del servidor de nombres (registry) correspondiente

3. Naming usa el stub para invocar el método

(32)

Servicio de Nombres (VIII)

„ Aplicación

rmiregistry

:

„ Contiene un objeto que implementa

java.rmi.registry.Registry

„ No es persistente

„ Por seguridad, no permite (de)registrar objetos

desde otra máquina

„ Cómo lanzar el servidor de nombres:

„ rmiregistry 50500

„ Desde código, en LocateRegistry:

(33)

Servicio de Nombres (IX)

„

Algunos inconvenientes:

„ No es independiente de la localización:

„ La URL del objeto lleva la dirección y puerto del rmiregistry correspondiente

„ Si el rmiregistry cambia de máquina, hay que cambiar los “clientes” o configurarlos para que “lean” la localización actual de algún sitio

„ Es una estructura de nombres “plana”

„ No se permiten jerarquías (ej.: /is2/MessageWriter) „ No es escalable

(34)

Ejemplo de Servidor

import java.rmi.* ;

public class HelloServer {

public static void main(String [] args) throws Exception { MessageWriter server = new MessageWriterImpl() ; Naming.rebind(“messageservice”, server) ;

} }

HelloServer.java

(35)

Ejemplo de Cliente

import java.rmi.* ;

public class HelloClient {

public static void main(String [] args) throws Exception {

MessageWriter server = (MessageWriter) Naming.lookup( “rmi://hendrix.cps.unizar.es/messageservice”) ;

server.writeMessage(“Hello, world”) ; }

}

(36)

A la vista de los ejemplo, ¿cuándo

tenemos que referenciar los

stubs

y

skeletons

en el código?

Se manejan transparentemente

(37)

Intercambio de Referencias

Remotas

„

Se pueden pasar como argumentos, y

devolver como resultados, referencias a

objetos remotos

public interface Printer extends Remote {

void print(String document) throws RemoteException ; }

public interface PrinterHub extends Remote { Printer getPrinter(int dpi, boolean isColor)

throws RemoteException ; }

objeto remoto

(38)

¿Qué pasa si un objeto remoto

recibe peticiones simultáneas de

varios clientes?

Política multithread

(39)

Política

Multithread

„ Invocaciones de diferentes clientes pueden

ejecutarse concurrentemente en diferentes

threads

(ej., un

thread

por petición)

„ Por tanto, la clase que implementa el

interface

remoto tiene que ser

thread-safe

„ Uso del modificador

synchronized

(40)

Resumen Clases Java (I)

„

java.rmi.Remote

„

java.rmi.RemoteException

„

java.rmi.server.UnicastRemoteObject

„

java.rmi.activation.Activatable

„

java.rmi.server.RemoteRef

(41)

Resumen Clases Java (II)

„

java.rmi.Naming

„

java.rmi.registry.Registry

„

java.rmi.registry.LocateRegistry

„

java.rmi.UnmarshalException

„

java.rmi.RMISecurityManager

(42)

Resumen Clases Java (III)

„

java.rmi.server.RMISocketFactory

„

java.rmi.server.RMIServerSocketFactory

„

java.rmi.server.RMIClientSocketFactory

(43)

Agradecimientos

Algunas de las transparencias e ideas de esta presentación están inspiradas o han sido adaptadas de trabajos de:

Celsina Bignoli (http://www.smccd.edu/accounts/bignolic/) Bryan Carpenter (http://www.hpjava.org/courses/arl)

(44)

Referencias

„ RMI Trail (The Java Tutorial, Sun): http://java.sun.com/docs/books/tutorial/rmi/index.html

„ Remote Method Invocation Home (Sun): http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp „ RMI Specification (Sun):

(45)
(46)
(47)

Ejemplo de Clase

Stub

public final class MessageWriterImpl_Stub

extends java.rmi.server.RemoteStub

implements MessageWriter, java.rmi.Remote { . . .

public MessageWriterImpl_Stub(java.rmi.server.RemoteRef ref) { super(ref);

}

public void writeMessage(java.lang.String $param_String_1) throws java.rmi.RemoteException { try {

ref.invoke(this, $method_writeMessage_0,

new java.lang.Object[] {$param_String_1}, 4572190098528430103L);

} . . . }

}

(48)

Tipos de Objetos Remotos

„ Antes hemos visto un ejemplo de

unicast

remote object

:

„ Permanece en memoria

„ El servidor debe estar siempre en funcionamiento

„ También hay

activable objects

:

„ El objeto se activa la primera vez que se invoca un

método del mismo (en lugar de estar esperando)

„ Se puede desactivar (salir de memoria) mientras

ningún cliente lo utilice

Extender java.rmi.server.UnicastRemoteObject o java.rmi.activation.Activatable

java.rmi.activation rmid tool

(49)

Recolección de Basura

Distribuida

„ Desasigna memoria automáticamente „ En el caso de objetos remotos:

„ Una capa de referencias remotas:

„ En el servidor, mantiene una cuenta de referencias

„ En el cliente, notifica al servidor cuando deja de usar una

referencia que mantiene localmente

„ Cuando la cuenta llega a 0, el servidor recolecta el objeto

remoto

„ Un cliente con una referencia remota debe renovar

(50)

¿Cuándo termina la ejecución de

un programa servidor?

Depende de si sus objetos remotos se han

registrado objetos en el servicio de nombres o

no…

(51)

¿Necesita el cliente tener la clase

del

stub

en su máquina?

No necesariamente al comienzo

(52)

Carga Dinámica de Clases (I)

„

La serialización almacena los datos, no

el código

„

Si al deserializar no se encuentra la

clase:

„

java.rmi.UnmarshalException

„

java.lang.ClassNotFoundException

(excepción anidada)

(53)

Carga Dinámica de Clases (II)

„ ¿Cómo podemos hacer la clase disponible en la

máquina correspondiente?

„ Copiar las clases manualmente y situarlas en el

CLASSPATH

„ Utilizar un servidor web de clases:

„ Establecer la propiedad java.rmi.server.codebase, que se

embebe automáticamente en la serialización (salvo si la clase se descargó de otra URL, en cuyo caso se embebe dicha URL)

„ Cuando se deserializa el objeto en destino, la JVM puede

(54)

Carga Dinámica de Clases (III)

„

Para permitir la descarga de clases, hace

falta establecer un

SecurityManager

(con

una

security policy

):

System.setSecurityManager(new java.rmi.RMISecurityManager()) ;

„

Y definir una propiedad

java.security.policy

.

grant {

permission java.security.AllPermission; };

(55)

Hablando de clases en general (no

de stubs), si el cliente no tiene una

clase necesaria localmente, ¿cómo lo

vamos a compilar?

Por ejemplo, podría necesitar recibir una

clase más específica (subclase) que la que tiene

(56)

¿Cómo es posible que el servidor

no se caiga si matamos el

rmiregistry

?

Sólo es un servicio de nombres

(57)

Más Sobre el Intercambio de

Referencias Remotas

„ Una referencia remota no es literalmente una

referencia a un objeto Java en otra máquina virtual: „ Es una referencia a un objeto Java local (que es una

instancia de una clase stub) que implementa el mismo interface

„ Si intentamos hacer un cast de la referencia a una clase de

implementación: ClassCastException

„ Si un argumento o resultado de un método remoto

implementa Remote, el tipo declarado debe ser un interface remoto, no puede ser una clase de implementación remota

(58)

Serialización en Java

„ Transformación de un objeto en un flujo

(

stream

) de bytes, representación externa

„ La clase debe implementar el interface

Serializable

(

NotSerializableException

):

„ Es posible que haya que implementar los métodos

readObject() y writeObject()

„ Una clase que sólo referencia valores primitivos y

clases serializables, también lo es

(59)

Callbacks

„

Un cliente puede pasar una referencia a

sí mismo en el servidor

„

El servidor puede usar la referencia

para llamar a métodos remotos del

Referencias

Documento similar

El desarrollo de la presente Tesis, se ha basado en el diseño e implementación de una aplicación cliente-servidor que permitiera al cliente gestionar de forma dinámica la reserva

Se indica, para cada flujo y sentido (cliente-servidor y servidor-cliente para los juegos, sólo este último para el streaming, punto a punto para VoIP), tanto el tamaño medio de

3 27.2% representado por varones que abrieron una pequeña y mediana en el distrito (INEI, 2021) , lo cual evidencia la escasa predisposición de los usuarios para

El diagrama de despliegue para este sistema incluye la representación de una PC que realiza la función de servidor y una o más PCs Cliente conectadas al Servidor por medio

El servidor de peticiones retorna la unidad de tra- bajo creada para el cliente (ver caso de uso Atender Tarea Asignada por el Servidor Central. Sección Crear una Unidad de

Un servidor que ejecuta Windows Server 2003 almacena la configuración del sistema, información de las 

Cabe mencionar que este sistema es el punto de referencia para determinar si el reporte cumplió o no con el nivel de servicio establecido por IBM para cada cliente y

El cliente solicita el servicio de pintura electroforetica, se acuerdan los tiempos de entrega tanto del cliente como de la empresa, el cliente envía el material a Electro Pintura,