Calendario esercitazioni e laboratori 29 Marzo esercitazione 12 Aprile esercitazione 26 Aprile laboratorio (lab721) 2 Maggio laboratorio (lab721) 3 Maggio esercitazione 9 Maggio laboratorio (???) 17 Maggio esercitazione 30 Maggio laboratorio (???) Serializzazione Java Esercitazione di Sistemi Distribuiti Leonardo Mariani mariani@disco.unimib.it Serializzazione Applicazioni della Serializzazione La serializzazione è il processo di trasformazione di un oggetto (o di un grafo di oggetti) in uno stream di byte La deserializzazione (o ripristino) è il processo inverso, cioè la ricostruzione dell oggetto (o del grafo di oggetti) che corrisponde ad uno stream di byte Implementazione dei meccanismi di persistenza Trasmissione di oggetti nella rete alla base delle tecnologie per applicazioni OO distribuite Non esiste solo la serializzazione Java es.,.net, XML,...
Complicazioni 1/2 Complicazioni 2/2 Non è difficile intuire cosa avviene per un oggetto semplice: public class Point implements java.io.serializable { private int x; private int y; Public Point(int x, int y) { this.x = x; this.y = y; } } Cosa accade per un grafo di oggetti? Cosa accade se si vuole serializzare solo parte del grafo? Cosa accade se il ricevente non conosce il tipo (la classe) corrispondente all oggetto serializzato? E se i processi in comunicazione hanno versioni diverse della stessa classe? Cosa accade se solo parte dello stato di un oggetto è serializzabile? Argomenti Trattati Oggetti Serializzabili Il comportamento della Serializzazione Modificare il comportamento della serializzazione Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà Gli oggetti Java sono serializzabili fanno eccezioni quelli che fanno riferimento a risorse native del sistema Serializzazione/Deserializzazione Un oggetto può essere serializzato usando il metodo writeobject(object ) della classe ObjectOutputStream. Un oggetto può essere ripristinato usando il metodo readobject() della classe ObjectInputStream. Metadati La serializzazione include dei metadati nella rappresentazione dell oggetto che sono poi usati nella deserializzazione.
Esempio 01 serializzazione di un vettore di Integer Esempio 02 serializzazione di un oggetto di tipo Point L interfaccia java.io.serializable Esempio 03 Gli oggetti serializzabili devono essere esplicitamente dichiarati nelle corrispondenti classi si implementa l interfaccia java.io.serializable l interfaccia non implementa nessun metodo, serve solo da marcatore serializzazione di un oggetto di tipo Point Il tentativo di serializzare un oggetto non serializzabile provoca la generazione della eccezione java.io.notserializableexception La serializzazione indiscriminata di qualsiasi oggetto può risultare dannosa per il sistema, es., prestazioni e sicurezza
Oggetti Complessi Gli attributi di stato di un oggetto possono essere a loro volta oggetti Cosa vi aspettate che accada se tentate di serializzare un oggetto di tipo Padre? Esempio 04 serializzazione di un oggetto Padre Chiusura Transitiva gli oggetti referenziati da un oggetto serializzato sono serializzati con l oggetto stesso altrimenti sarebbe onere del programmatore mantenere la consistenza delle informazioni serializzate assieme ad un oggetto Osservazione: in questo modo si può rischiare di serializzare una intera applicazione quando un oggetto viene serializzato!! Transient transient può essere usato nella dichiarazione di un attributo di una classe un attributo transient non viene serializzato con il proprio oggetto se si dichiara come transient l attributo lavoro nella classe persona dell esempio 04 cosa accade durante la deserializzazione?
Esempio 05 esempio 04 modificato, l attributo lavoro della classe Persona è transient. Oggetti non Serializzabili Cosa accade se nel grafo di oggetti da serializzare sono inclusi oggetti non serializzabili? Viene generata una eccezione java.io.notserializableexception Argomenti Trattati Rami Pendenti... Il comportamento della Serializzazione Modificare il comportamento della serializzazione Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà L attributo transient è spesso usato per evitare che vengano serializzati dei riferimenti a delle risorse locali Tali attributi andrebbero propriamente ri-inizializzati durante la deserializzazione Esempio, un agente mobile mantiene un riferimento alla piattaforma di esecuzione corrente. L agente viene serializzato per spostarsi nella nuova piattaforma. Durante la de-serializzazione il riferimento dovrebbe essere aggiornato alla nuova piattaforma. Come realizzarlo???
Modifica del comportamento di default della serializzazione è possibile implementare i metodi private readobject(objectinputstream) private writeobject(objectoutputstream) questi metodi sono invocati per leggere e scrivere oggetti serializzati questi metodi possono essere sovrascritti per modificare il comportamento della serializzazione Esempio 06 Agent mobile che viene serializzato e ripristinato. Nella serializzazione viene troncato il riferimento alla piattaforma locale, che è poi ripristinato durante la deserializzazione. Implementazione di writeobject e readobject I metodi possono essere implementati in modo da cambiare completamente il meccanismo di serializzazione Es., serializzazione in uno stream XML Oggetti Esternalizzabili Un oggetto può implementare java.io.externalizable invece di java.io.serializable bisogna implementare void writeexternal(objectoutput out) void readexternal(objectinput in) in questo caso i meccanismi di serializzazione DEVONO essere implementati manualmente
Argomenti Trattati Variabili Statiche Il comportamento della Serializzazione Modificare il comportamento della serializzazione Cosa accade quando un oggetto serializzato usa variabili statiche? Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà Esempio 07 Un padre che cerca di mantenere traccia dei propri figli... Consistenza della deserializzazione con le variabili statiche le variabili statiche sono variabili di classe e quindi non devono essere serializzate con un oggetto un oggetto deserializzato automaticamente accede alle variabili statiche esistenti nel momento del suo ripritino le variabili statiche indicano proprietà del contesto in cui l oggetto è eseguito quando il valore delle variabili statiche dipende dagli oggetti presenti nel sistema, il ripristino di un oggetto deve essere implementato opportunamente (consistenza deserializzazione<->costruzione)
Esempio 08 Un padre che riesce a mantenere traccia dei propri figli. Argomenti Trattati Il comportamento della Serializzazione Modificare il comportamento della serializzazione Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà Il Problema delle Versioni La versione di una classe usata per la serializzazione di un oggetto può essere differente rispetto a quella usata per ripristinarlo, es. upgrade del sistema comunicazione con applicazioni remote serialversionuid E un numero a 64bit che viene associato ad ogni classe Dipende dai metadati (metodi, attributi,...) la JVM confronta il serialversionuid di un oggetto e della classe a disposizione per stabilirne la compatibilità serialver <classname> permette di conoscere il servialversionuid di una classe
Compatibilità tra le Versioni Esempio 09 1.0 host A 2.0 host B scrittura di un oggetto in una nuova versione a) writeobject 1.0 host A 2.0 host B readobject b) 1.0 host A 2.0 host B Argomenti Trattati Il comportamento della Serializzazione Modificare il comportamento della serializzazione Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà Scritture ripetute dello stesso oggetto Cosa accade se si serializza un oggetto di tipo Padre? Cosa accade se si serializza per due volte un oggetto di tipo Lavoro?
Token Per evitare che uno stesso oggetto sia scritto più volte in uno stream si usano dei tokens numerici Esempio writeobject(padre) 1 padre 2 figlio 1 3 lavoro 4 indirizzo stream Un token è un identificatore di un oggetto serializzato per lo stream preso in considerazione writeobject(lavoro) writeobject(lavoro) 1 lavoro 2 indirizzo 1 stream Identificazione degli oggetti Garbage Collection tabella dei riferimenti 1 2 3 4 padre figlio 1 lavoro indirizzo 1 2 3 14 stream Problema: anche se un oggetto serializzato perde tutti i suoi riferimenti non può essere vittima del garbage collection, infatti il riferimento dello stream rimane Soluzione: invocazione di reset() sullo stream! reset elimina il contenuto della tabella dei riferimenti. ma attenzione al suo uso...
Esempio 10 Esempio 11 Abusare di reset può portare alla duplicazione di oggetti...... ma non usarlo può portare alla perdita di informazioni importanti Argomenti Trattati Ereditarietà Il comportamento della Serializzazione Modificare il comportamento della serializzazione Consistenza costruttori<->deserializzazione Gestione delle Versioni Mantenimento dell Identità e Garbage Collection Serializzazione ed Ereditarietà Considerate una classe Persona (non serializzabile) ed una classe Studente (serializzabile). La classe Studente estende la classe Persona. Studente è serializzabile? Se si tenta di serializzare uno Studente cosa accade?
Esempio 12 serializzazione dello studente Ripristino di oggetti con stato parzialmente serializzabile Un oggetto serializzabile ha uno stato composto da due parti: la parte serializzabile la parte non serializzabile Il ripristino della parte serializzabile è gestito dal metodo readobject Il ripristino della parte non serializzabile è gestito dai costruttori Conclusioni Il comportamento di default della serializzazione si adatta bene alla maggior parte dei casi, ma bisogna considerare uso dei transient per limitare il grafo serializzato ridefinizione dei processi di serializzazione/deserializzazione consistenza tra il ripristino degli oggetti e l ambiente gestione degli upgrades meccanismo dei tokens classi serializzabili che ereditano da classi non serializzabili