Práctica III: Java RMI con Serialización y Activation Framework.

26
Práctica III: Java RMI con Serialización y Activation Framework

Transcript of Práctica III: Java RMI con Serialización y Activation Framework.

Page 1: Práctica III: Java RMI con Serialización y Activation Framework.

Práctica III: Java RMI con Serialización y

Activation Framework

Page 2: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

2

Persistencia

• Caso práctico: JINI– Necesitamos que el servicio de impresión esté

siempre conectado de manera que, si existe algún “crash” de la máquina, el servicio arranque automáticamente.

– Por otra parte, el servicio de control de entrada no tiene por qué estar arrancado todo el rato; se espera que JINI lo pueda para y rearrancar “on demand”.

Page 3: Práctica III: Java RMI con Serialización y Activation Framework.

1.- Serialización en Java

Page 4: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

4

Serialization

• Proceso de conversión de un conjunto de instancias referenciadas entre sí a un flujo lineal de bytes (byte stream) para que:– puedan enviarse por un socket,– puedan almacenarse en un fichero,– puedan ser manipulados como un stream más.

Page 5: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

5

Opción 1: invocación remota Servidor - Cliente

• Prestaciones

• Vulnerable a fallos parciales

• ¡¡¡Volvemos al problema de RPC y stateless se

rvers!!!

Page 6: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

6

Opción 2: envío de copias de la instancia de C a S

• Los dos objetos son independientes entre sí.Los dos objetos son independientes entre sí.

• El mecanismo de copia ha de crear DEEP El mecanismo de copia ha de crear DEEP COPIES.COPIES.

• Si un objeto se envía dos veces en métodos Si un objeto se envía dos veces en métodos remotos diferentes, son dos copias distintas remotos diferentes, son dos copias distintas (¡pensad en las DEEP COPIES!)(¡pensad en las DEEP COPIES!)

Page 7: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

7

Usos de la Serialización

• Como mecanismo de persistencia:– se utiliza el stream “FileOutputStream” para almacenar

objetos en ficheros.

• Como mecanismo de copia:– se utiliza el ByteArrayOutputStream que se puede

almacenar en memoria para después crear duplicados.

• Como mecanismo de comunicación:– capturar o enviar el stream mediante sockets.

Page 8: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

8

Cómo hacer que una clase sea Serializable

• Ha de implementar la interfaz Serializable,

• Asegurarse de que el estado local es serializado apropiadamente,

• Asegurarse de que el estado de la superclase se serializa apropiadamente,

• Sobrecargar equals()equals() y hashCode().hashCode().

Page 9: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

9

Implementar interfaz Serializable

• Obvio y fácil.

Page 10: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

10

Estado local serializado correctamente (I)

• Los atributos de una clase serializable han de ser o primitivos o serializables.public class ArrayList extends AbstractList public class ArrayList extends AbstractList

implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {private Object elementData[];private Object elementData[];private int size;private int size;……

}}

public class ArrayList extends AbstractList public class ArrayList extends AbstractList implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {

private Object elementData[];private Object elementData[];private int size;private int size;……

}}

• Si eso no se cumple:– Campos declarados como transienttransient.– Implementar métodos writeObject/readObjectwriteObject/readObject.– Declaración de serialPersistentFieldsserialPersistentFields.

Page 11: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

11

Estado local serializado correctamente (II): transient

• Vamos, ignorar la variable al serializar.

• Útil si la variable no afecta al estado del objeto.

• Útil si la variable no es serializable, para evitar excepciones al serializar.

public class ArrayList extends AbstractList public class ArrayList extends AbstractList implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {

private transient Object elementData[];private transient Object elementData[];private int size;private int size;……

}}

public class ArrayList extends AbstractList public class ArrayList extends AbstractList implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {

private transient Object elementData[];private transient Object elementData[];private int size;private int size;……

}}

Page 12: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

12

Estado serializado (III): [write|read]Object

• La variable no es serializable, pero QUEREMOS SERIALIZARLA.

• Implementamos dos métodos:– private void writeObject(java.io.ObjectOutputStream out)

throws IOException

– private void readObject(java.io.ObjectInputStream in)throws IOException, ClassNotFoundException

public class ArrayList extends AbstractList public class ArrayList extends AbstractList implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {

private transient Object elementData[];private transient Object elementData[];private int size;private int size;

private synchronized void writeObject(java.io.ObjectOutputStream stream)throws java.io.IOException {

stream.defaultWriteObject();stream.writeInt(elementData.length);for(int i = 0; i < size; i++)

stream.writeObject(elementData[i]);}

}}

public class ArrayList extends AbstractList public class ArrayList extends AbstractList implements List, Cloneable, Serializable {implements List, Cloneable, Serializable {

private transient Object elementData[];private transient Object elementData[];private int size;private int size;

private synchronized void writeObject(java.io.ObjectOutputStream stream)throws java.io.IOException {

stream.defaultWriteObject();stream.writeInt(elementData.length);for(int i = 0; i < size; i++)

stream.writeObject(elementData[i]);}

}}

Page 13: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

13

Estado serializado (IV):serialPersistentFields

• Declaración explícita de qué variables serializar, mediante un atributo static final:

private static final ObjectStreamField[]

serialPersistentFields = { new

ObjectStreamField(“size”, Integer.TYPE), …};

Page 14: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

14

Superclase serializada adecuadamente

• Si la superclase es Serializable, OK.• Si no, hay que almacenar su estado:

– serialPersistentFields

– writeObject/readObject.

• ¿Qué pasa si la superclase no la conozco en detalle?

• Además, las clases no serializables, para poder serlo, han de tener un constructor con cero argumentos (¡¡!!)

REFACTORING

Page 15: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

15

Sobrecarga de equals() y hashCode()

• Primero:– ByteArrayOutputStream memoryOutputStream = new

ByteArrayOutputStream( );– ObjectOutputStream serializer = new

ObjectOutputStream(memoryOutputStream);– serializer.writeObject(serializableObject);– serializer.flush( );

• Después:– ByteArrayInputStream memoryInputStream = new

ByteArrayInputStream(memoryOutputStream.toByteArray( ));– ObjectInputStream deserializer = new

ObjectInputStream(memoryInputStream);– Object deepCopyOfOriginalObject =

deserializer.readObject( );• Y ahora...

– serializableObject.equals(deepCopyOfOriginalObject)

public class Money extends ValueObject {private int _cents;...

}

• en este caso debería de devolver true, pero devuelve false• igual ocurre con hashCode, pues dos instancias iguales deben devolver el mismo hashCode.

public class Money extends ValueObject {private int _cents;...

}

• en este caso debería de devolver true, pero devuelve false• igual ocurre con hashCode, pues dos instancias iguales deben devolver el mismo hashCode.

Page 16: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

16

Ejemplo 1: clases preserializables

• Envío de objetos mediante sockets

Page 17: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

17

Ejemplo 2: utilización de read/writeObject

• Se utiliza una matriz simétrica, por lo que optimizamos espacio modificando los métodos readObject y writeObject.

• No hay superclases.

Page 18: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

18

Ejemplo 3: superclase no serializable

• La superclase necesita un constructor sin argumentos.

• Los atributos de la superclase que no son serializados han de ser accesibles desde la superclase.

Page 19: Práctica III: Java RMI con Serialización y Activation Framework.

Activation Framework

Page 20: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

20

Activation Framework

• RMI Activation Framework.

• Es un servicio que se ocupa del ciclo de vida de un objeto Java, que puede o no estar en memoria principal– Concepto CORBA: Objeto vs. Servant.

Page 21: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

21

AF: RMI Activation Daemon (rmid)

• Es un proceso que asegura que los servicios “activables” están disponibles cuando se necesitan.

• Los servicios “activables” se comunican con rmid para registrarse: devuelven una referencia remota pero sin implementación activa.

• Rmid puede arrancar los servicios en la misma JVM o en una nueva.

Page 22: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

22

AF: RMI Activation Daemon (rmid): arquitectura del proceso

• El servicio activable corre en un proceso hijo de rmid.

• Si rmid cae, al tener un log, cuando sea rearrancado arrancará los servicios que tuviera activos.– Por tanto, un servicio ha de desrregistrarse

explícitamente.

Page 23: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

23

AF: Creando un servicio activable

• Interfaz Java: MyRemoteInterface– public interface MyRemoteInterface extends java.rmi.Remote

– Como todos.

• Clase de implementación: – public class ActivatableImplementation extends Activatable implements

examples.activation.MyRemoteInterface

– Ya no extiende UnicastRemoteObject.– Añade un ActivationId y un MarshalledObject

(representación serializada del objeto) al constructor.

Page 24: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

24

AF: Creando un servicio activable

• Creación de la clase “setup”: – Crea toda la información necesaria para la clase

activable, sin que sea necesario instanciar el objeto remoto. Se lo pasa al rmid.

– Crea un grupo de activación.– Crea una descripción de activación (clase, dónde

está e información serializada que pueda necesitar -no ahora-.

– Registra en rmid y en rmiregistry.

Page 25: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

25

AF: Compilación y ejecución

• Compilar interfaces remotas, clases, etc.

• Rmic

• Arrancar rmiregistry.

• Arrancar el activation daemon, rmid:– rmid -J-Dsun.rmi.activation.execPolicy=none

• Setup:– java -Djava.security.policy=<path>/policy -

Djava.rmi.server.codebase=file:///<path> examples.activation.Setup

• Cliente– java -Djava.security.policy=<path>\policy examples.activation.Cliente

<server>

Page 26: Práctica III: Java RMI con Serialización y Activation Framework.

Sistemas Distribuidos - Nebrija - Justo Hidalgo

26

Bibliografía

• Serialización:– http://www.oreilly.com/catalog/javarmi

• Activation Framework:– http://java.sun.com/j2se/1.3/docs/guide/rmi/

activation