Lezione n.6 LPR Informatica Applicata Serializzazione...

53
Dipartimento di Informatica Università degli studi di Pisa JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata Serializzazione JAVA (alcuni lucidi sono ripresi da appunti di Leonardo Puleggi) Università degli Studi di Pisa Dipartimento di Informatica 28/03/2013 Laura Ricci

Transcript of Lezione n.6 LPR Informatica Applicata Serializzazione...

Page 1: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 1

Lezione n.6LPR Informatica Applicata

Serializzazione JAVA(alcuni lucidi sono ripresi da appunti di

Leonardo Puleggi)

Università degli Studi di Pisa Dipartimento di Informatica

28/03/2013Laura Ricci

Page 2: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 2

SERIALIZZAZIONE

• in JAVA, ogni entità è rappresentata come un oggetto; se due entità vogliono comunicare si devono scambiare oggetti

• serializzazione: meccanismo che permette di salvare un oggetto o un grafo di oggetti su uno stream di byte che successivamente può essere salvato su un file inviato sulla rete

• deserializzazione: processo inverso, permette di ricostruire l'oggetto/il grafo di oggetti dallo stream di byte

• La serializzazione si basa sulla possibilità di scrivere lo stato di un oggetto in una forma sequenziale, sufficiente per ricostruire l'oggetto quando viene riletto.

Page 3: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 3

SERIALIZZAZIONE

La serializzazione di oggetti viene usata in diversi contesti:

inviare oggetti su uno stream che rappresenta una connessioneTCP

flattening di oggetti: trasformare un oggetto in un array di byte. Utilizzato per costruire pacchetti UDP.

inviare oggetti che sono parametri di metodi invocati via RMI

fornire un meccanismo di persistenza ai programmi, consentendo l'archiviazione di un oggetto.

● esempio: un programma che realizza una rubrica telefonica o un'agenda.

Page 4: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 4

JAVA: LA SERIALIZZAZIONE

• Meccanismo standard offerto da JAVA Le classi ObjectInputStream e ObjectOutputStream definiscono

streams (basati su streams di byte) su cui si possono leggere e scrivere oggetti.

per rendere un oggetto “persistente”, l'oggetto deve implementare l'interfaccia Serializable o ereditarne una implementazione dalla gerarchia di oggetti.

l'oggetto e tutti i suoi componenti debbono essere serializzabili non tutti gli oggetti possono essere serializzati.

Es: oggetti del sistema quali Thread, OutputStream e Socket non possono essere serializzate

• Altri meccanismi offerti da JAVA personalizzare il meccanismo di default (interfaccia Serializable) creare un proprio protocollo (classe Externalizable)

Page 5: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 5

JAVA: LA SERIALIZZAZIONE

In rosso le parti relative alla serializzazione

import java.io.Serializable;

import java.util.Date;import java.util.Calendar;

public class PersistentTime implements Serializable { private static final long serialversionUId=1; private Date time; public PersistentTime() {time = Calendar.getInstance().getTime(); } public Date getTime() {return time; }}

Page 6: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 6

JAVA: LA SERIALIZZAZIONE

import java.io.*;public class FlettenTime {public static void main(String [] args) {String filename = "time.ser"; if(args.length > 0) { filename = args[0]; } PersistentTime time = new PersistentTime(); FileOutputStream fos = null; ObjectOutputStream out = null; try

{ fos = new FileOutputStream(filename); out = new ObjectOutputStream(fos); out.writeObject(time); out.close(); } catch(IOException ex) {ex.printStackTrace();}}}

Page 7: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 7

JAVA: LA SERIALIZZAZIONEpublic class InflateTime{public static void main(String [] args) {String filename = "time.ser"; if(args.length > 0) {filename = args[0]; } PersistentTime time = null; FileInputStream fis = null; ObjectInputStream in = null; try {fis = new FileInputStream(filename); in = new ObjectInputStream(fis); time = (PersistentTime)in.readObject(); in.close(); } catch(IOException ex){ ex.printStackTrace(); } catch(ClassNotFoundException ex) {ex.printStackTrace();}

Page 8: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 8

JAVA: LA SERIALIZZAZIONE

// print out restored time System.out.println("Flattened time: " + time.getTime()); System.out.println(); // print out the current time System.out.println("Current time: "+ Calendar.getInstance().getTime());}}Output ottenuto:Flattened time: Mon Mar 12 19:11:55 CET 2012Current time: Mon Mar 12 19:16:24 CET 2012

ClassNotFoundException: l'applicazione tenta di caricare una classe, ma non trova nessuna definizione di una classe con quel nome

Page 9: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 9

JAVA: LA SERIALIZZAZIONE

• La versione viene utilizzata in fase di deserializzazione per verificare che le classi utilizzate da chi ha serializzato l'oggetto e da chi lo sta deserializzando siano compatibili (vedere second aparte della lezione)

• Il metodo ObjectInputStream.readObject() legge la sequenza di bytes memorizzati in precedenza e crea un oggetto che è l'esatta replica di quello originale

• Poichè readObject può leggere qualsiasi tipo di oggetto, è necessario effettuare un cast al tipo corretto dell'oggetto

• Il file con la specifica della classe deve essere accessibile quando si ricostruisce l'oggetto, altrimenti viene sollevata una ClassNotFoundException

Page 10: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 10

SERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

import java.io.Serializable;import java.util.*;

public class Padre implements Serializable {private static final long serialVersionUID = 1L;private String nome;private String cognome;private Collection<Figlio> figli;

public Padre(String nome,String cognome){this.nome=nome;this.cognome=cognome;figli=new ArrayList<Figlio>();

}

public void aggiungiFiglio(Figlio f){figli.add(f); }

Page 11: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 11

SERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

public String toString(){StringBuilder temp=new StringBuilder("Padre");temp.append("\n");temp.append("nome: ");temp.append(this.nome);temp.append("\n");temp.append("cognome: ");temp.append(this.cognome);emp.append("\n");temp.append("Figli: ");temp.append(figli.toString());

return temp.toString();}}

Page 12: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 12

SERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

import java.io.Serializable;

public class Figlio implements Serializable{private static final long serialVersionUID = 1L;

private String nome;private String cognome;

public Figlio(String nome,String cognome){ this.nome=nome; this.cognome=cognome; }

public String toString(){ return "nome: "+nome+" cognome: "+cognome; }}

Page 13: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 13

SERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

public class SerializzaPadre {

public static void main(String[] args) {Figlio a=new Figlio("mario","rossi");Figlio b=new Figlio("maria","rossi");

Padre p=new Padre("giovanni","rosso"); p.aggiungiFiglio(a); p.aggiungiFiglio(b); ObjectOutputStream output=null; try{ output=new ObjectOutputStream(new FileOutputStream("dati.dat")); } catch (FileNotFoundException e) { System.out.println("Impossibile trovare il file "); e.printStackTrace(); System.exit(1); } catch(IOException ioe){ System.out.println("Errore IO"); ioe.printStackTrace(); System.exit(1); }

Page 14: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 14

SERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

try { output.writeObject(p); }catch (IOException e1) { System.out.println("Impossibile serializzare l'oggetto " + p); e1.printStackTrace(); System.exit(1); } try { output.close(); } catch (IOException e2) { System.out.println("Impossibile chiudere lo stream "); e2.printStackTrace(); }System.out.println("Serializzazione completata.");

}}

Page 15: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 15

DESERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

import java.io.*;

public class DeSerializzaPadre {public static void main(String[] args) {ObjectInputStream ois = null;try { ois = new ObjectInputStream(new FileInputStream("dati.dat"));} catch (FileNotFoundException e) { System.out.println("Impossibile trovare il file "); e.printStackTrace(); System.exit(1);} catch (IOException e) { System.out.println("Errore nella creazione dello stream "); e.printStackTrace(); System.exit(1);}

Page 16: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 16

DESERIALIZZAZIONE: GRAFO DEI RIFERIMENTI

Padre p=null;try { p = (Padre) ois.readObject();} catch (IOException e1) { System.out.println("Errore nella creazione dello stream "); e1.printStackTrace(); System.exit(1); } catch (ClassNotFoundException e1) { System.out.println("Impossibile trovare la classe"); e1.printStackTrace(); System.exit(1); }System.out.println(p.toString());}}

Page 17: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 17

SERIALIZZAZIONE

• L'esempio precedente mostra che si possono serializzare/deserializzare oggetti che al loro interno fanno riferimento ad altri oggetti

• L'implementazione serializza transitivamente tutti gli oggetti riferiti

• Se però uno degli oggetti riferiti non è serializzabile, viene sollevata una NotSerializableException

• E' possibile non includere il valore di alcuni attributi nell'oggetto serializzato, mediante l'utilizzo della parola chiave transient

Page 18: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 18

SERIALIZZAZIONE

import java.io.Serializable;import java.util.*;

public class Padre implements Serializable {private static final long serialVersionUID = 1L;

private String nome;private String cognome;transient private Collection<Figlio> figli;….....

Page 19: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 19

SERIALIZZAZIONE

• l'attributo transient inserito nell'esempio precedente indica che non si vuole serializzare l'attributo Figli della classe Padre

• la parola chiave transient limita la visita nell'albero dei riferimenti

• tutti gli altri attributi vengono salvati

• se si esegue la serializzazione e quindi la deserializzazione, il campo figli nell'oggetto deserializzato, risulta uguale a null

Page 20: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 20

LA SERIALIZZAZIONE STEP BY STEP

Cosa avviene quando un oggetto viene serializzato? Si registrano sullo stream:• i “magic data”

STREAM_MAGIC = “acde” STREAM_VERSION = versione della JVM

• I metadati che descrivono la classe associata alla istanza dell'oggetto serializzato (La classe Padre nell'esempio precedente) La descrizione include il nome della classe, il serialVersionUID della

classe, il numero di campi, altri flag.• I metadati di eventuali superclassi, fino a raggiungere java.lang.Object• I valori associati all'oggetto istanza della classe, partendo dalla super

classe top most• I dati degli oggetti eventualmente riferiti dall'oggetto istanza della

classe, iniziando dai metadati e poi registrando i valori. (Le istanze della classe Figlio, nell'esempio precedente).

• Non si registrano i metodi della classe

Page 21: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 21

LA SERIALIZZAZIONE STEP BY STEP

• Consideriamo la classe SimpleClass con campi firstName,

lastName,

weight

Location

• L'oggetto istanza della classe contiene i campi {"Brad","Pitt",180.5, {49.345, 67.567}}

• A fianco:risultato della serializzazione

• Notare: per la memorizzazione di un oggetto di 20 bytes utilizzati circa 220 bytes

Page 22: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 22

LA SERIALIZZAZIONE: “UNDER THE HOOD”

Meccanismi implementati dalla JVM che è importante conoscere per utilizzare la serializzazione in modo corretto:

Caching

Controllo delle versioni

Deadlock

Performance

Page 23: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 23

SERIALIZATION CACHE

public class BigData { private static final long TERA_BYTE = 1024L * 1024 * 1024 * 1024; public static void main(String[] args) throws IOException { long bytesWritten = 0; byte[] data = new byte[100 * 1024 * 1024]; ObjectOutputStream out = new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream("bigdata.bin") ) ); long time = System.currentTimeMillis();

Page 24: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 24

SERIALIZATION CACHEfor (int i = 0; i < 10 * 1024 * 1024; i++) { out.writeObject(data); bytesWritten += data.length; } out.writeObject(null); out.close(); time = System.currentTimeMillis() - time; System.out.printf("Wrote %d TB%n", bytesWritten / TERA_BYTE); System.out.println("time = " + time); } }Wrote 1000 TB Time = 3693

Ma la dimensione del file bigdata.bin è solo di 150 M. Come è possibile???

Page 25: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 25

SERIALIZATION CACHE

• Ogni qual volta un oggetto viene serializzato e inviato ad una ObjectOutputStream, la sua identità viene memorizzata in una “identity hash table”

• Se l'oggetto viene scritto nuovamente sull'OutputStream, l'oggetto stesso non viene nuovamente serializzato, ma viene memorizzato un puntatore all'oggetto serializzato in precedenza scopo: minimizzazione delle scritture e risoluzione di relazioni

circolari tra oggetti• Comportamento analogo quando si legge da uno stream: l'oggetto letto

viene memorizzato in una “identity hash table”, la prima volta Letture future fanno riferimento allo stesso oggetto

• Possibili inconsistenze quando lo stato dell'oggetto viene modificato La modifica viene persa sull'ObjectOutputStream, perchè non viene

aggiornato lo stato

Page 26: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 26

SERIALIZZAZIONE: BUFFERIZZAZIONE

Un esempio che dimostra i problemi che può dare un serialization cache:

import java.io.*; public class MyObject implements Serializable{ private static final long serialVersionUID = 1L; private int x; public MyObject(){ }; public void set( int x) {this.x=x;} public int get() {return x;}; }

Page 27: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 27

SERIALIZZAZIONE: BUFFERIZZAZIONE

import java.io.*; import java.net.*;public class SerializationClient { public static void main (String Args [] ) throws Exception { Socket s= new Socket("localHost",4000); ObjectOutputStream out = new ObjectOutputStream (s.getOutputStream());

MyObject myobj = new MyObject(); myobj.set(100); out.writeObject(myobj); myobj.set(200); out.writeObject(myobj); } }

Page 28: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 28

SERIALIZZAZIONE: BUFFERIZZAZIONE

import java.net.*;import java.io.*;public class SerializableServer { public static void main(String args[]) throws Exception {ServerSocket ss = new ServerSocket(4000); Socket s=ss.accept(); ObjectInputStream ois= new ObjectInputStream (s.getInputStream()); MyObject myobj = (MyObject)ois.readObject(); System.out.println(myobj.get()); myobj = (MyObject)ois.readObject(); System.out.println(myobj.get());

}} OUTPUT 100 100

Page 29: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 29

SERIALIZZAZIONE: CACHING

import java.io.*;

import java.util.Arrays;

public class FillCache {

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

byte[] data = new byte[10 * 1024 * 1024];

ObjectOutputStream out = new ObjectOutputStream(

new BufferedOutputStream(

new FileOutputStream("smalldata.bin") ) );

for (int i = -128; i < 128; i++) {

Arrays.fill(data, (byte) i);

out.writeObject(data);

}

out.writeObject(null);

out.close();

} }

Page 30: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 30

SERIALIZZAZIONE: CACHING

import java.io.*;

public class ReadCache {

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

ObjectInputStream in = new ObjectInputStream(

new BufferedInputStream(

new FileInputStream("smalldata.bin")

)

);

byte[] data;

while ((data = (byte[]) in.readObject()) != null) {

System.out.println(data[0]); }

in.close(); } }

Page 31: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 31

SERIALIZZAZIONE: CACHING

• La stampa ottenuta: -128, -128, -128, …..

• Perdita di valori dovuta al meccanismo di serializzazione

• Al momento della deserializzazione, si legge il vettore contenente 128 la prima volta e si memorizza nella “identity hash table”

• Quando legge un puntatore all'oggetto, si ricerca il valore dell'oggetto dalla cache locale

• Il meccanismo di serializzazione ignora se l'oggetto è stato modificato

Page 32: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 32

SERIALIZZAZIONE: CACHING

import java.io.*;

import java.util.Arrays;

public class FillCache1 {

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

ObjectOutputStream out = new ObjectOutputStream(

new BufferedOutputStream( new FileOutputStream("verylargedata.bin")));

for (int i = -128; i < 128; i++) {

byte[] data = new byte[10 * 1024 * 1024];

Arrays.fill(data, (byte) i);

out.writeObject(data);

}

out.writeObject(null);

out.close(); } }

Page 33: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 33

SERIALIZZAZIONE: CACHING

Risultato ottenutoException in thread "main" java.lang.OutOfMemoryError: Java heap spaceat FillCache1.main(FillCache1.java:13)

Il file generato è di dimensioni molto grandi

Ogni volta che un oggetto viene scritto sullo stream, esso viene posto nella “identity hash table”

Rimane nella table finchè non viene effettuata una reset sullo stream

Page 34: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 34

SERIALIZZAZIONE: CACHING

import java.io.*;

import java.util.Arrays;

public class FillCache2 {

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

ObjectOutputStream out = new ObjectOutputStream(

new BufferedOutputStream(

new FileOutputStream("verylargedata.bin")) );

byte[] data = new byte[10 * 1024 * 1024];

for (int i = -128; i < 128; i++) {

Arrays.fill(data, (byte) i);

out.writeObject(data);

out.reset(); }

out.writeObject(null);

out.close(); } }

Page 35: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 35

SERIALIZZAZIONE: CACHING

• La stampa ottenuta -128, -127, -126, …

• Il programma non segnala un OutOfMemory Error

• La reset effettua il flush della tabella dopo ogni operazione di scrittura

• Ad ogni write un nuovo oggetto sullo stream

• Svantaggio: nessuna ottimizzazione, tutti i valori(anche i campi che non hanno cambiato valore) eliminati dalla cache

• Infatti il programma richiede molto tempo per terminare

Page 36: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 36

IL CONTROLLO DELLE VERSIONI

• supponiamo di creare una classe i cui oggetti siano serializzabili

• serializziamo un oggetto istanza di quella classe

• problema: se cambio la specifica della classe, possono le istanze serializzate secondo la vecchia specifica essere deserializzate come istanze della nuova classe? in generale questo non è possibile

• meccanismo di controllo delle versioni ad ogni classe serializzabile viene attribuito un identificatore unico, il SerialVersionUID

Tale identificatore viene rigenerato ogni volta che viene modificata la classe

Page 37: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 37

IL CONTROLLO DELLE VERSIONI

• Il serialVersionUID viene generato a partire dal codice della classe

• Modificando il codice si modifica il serialVersionUID

• Generato al momento di una serializzazione/deserializzazione

• Quando deserializzo, se ho modificato il codice, la deserializzazione fallisce si tenta di rileggere l'oggetto, la ricostruzione dell'oggetto fallisce

e viene sollevata una java.io.InvalidClassException

Page 38: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 38

IL CONTROLLO DELLE VERSIONI

• SerialVersionUID utilizzato in fase di deserializzazione per verificare che il mittente ed il destinatario di un oggetto serializzato fanno riferimento a classi compatibili

• Le classi in realtà potrebbero essere compatibili

• Possibile, in questo caso, specificare esplicitamente il serialVersionUID e forzarlo uguale nelle due versioni

• Specifica serialVersionUID: il valore può essere qualsiasi valore long

private static final long serialVersionUID = 3487495895819393L;

Page 39: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 39

IL CONTROLLO DELLE VERSIONI

• Specifica serialVersionUID: il valore può essere qualsiasi valore long private static final long serialVersionUID = 3487495895819393L;

• Il meccanismo di serializzazione controlla se l'utente ha dichiarato esplicitamente un valore per il serialVerisonUID ed, in questo caso, usa questo valore, invece di calcolarlo in modo automatico

• Se in una classe non esiste una dichiarazione esplicita di un serialVersionUID, il meccanismo di serializzazione lo calcola automaticamente

• Dichiarazione esplicita di serialVersionUID: per garantire valori consistenti tra diverse implemetazioni di compilatori JAVA

Page 40: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 40

CONTROLLO DELLE VERSIONI

• L'identificatore della classe in Eclipse puntando il mouse sul nome di una classe Serializzabile appare

una finestra che permette di generare automaticamente un SerialVersionID

Page 41: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 41

CONTROLLO DELLE VERSIONI

• L'identificatore della classe in Eclipse puntando il mouse sul nome di una classe Serializzabile appare

una finestra che permette di generare automaticamente un SerialVersionID

utilizzando add generated serial version ID

Page 42: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 42

OBJECT STREAM: DEADLOCK

• Supponiamo che un'applicazione A1 apra una connessione verso A2 per inviare ad A2 uno stream di oggetti

• A1 associa alla connessione un ObjectOutputStream, mentre A2 associa alla medesima connessione un ObjectInputStream

• Quando A1 crea l'ObjectOutputStream, viene registrato uno sullo stream un header che viene quindi inviato sulla connessione

• Quando A2 crea l' ObjectInputStream– la JVM accede tenta di recuperare l'header dello stream dal socket

associato alla connessione– se l'header non è presente, la JVM si blocca in attesa di ricevere

l'header sul socket– ATTENZIONE: per prevenire situazioni di deadlock occorre porre

attenzione sull'ordine con cui vengono creati gli stream di Input/Output

Page 43: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 43

OBJECT INPUT/OUTPUT STREAM: DEADLOCK

Se i due partners della connessione eseguono entrambi il seguente frammento

di codice (s è il socket associato alla connessione)ObjectInputStream in = new ObjectInputStream(s.getInputStream( ));ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream( ));si verifica una situazione di deadlock..

Infatti,

• entrambi tentano di leggere l'header dello stream dal socket

• l'header viene generato quando viene viene creato l'ObjectOutputStream

• nessuno dei due è in grado di generare l'ObjectOutputStream,

perchè bloccato

• E' sufficiente invertire l'ordine di creazione degli stream in uno dei partner

Page 44: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 44

JAVA: LA SERIALIZZAZIONE

• Il meccanismo di default offerto da JAVA è generale e le prestazioni non risultano quindi ottime i riferimenti agli oggetti sono memorizzati nella cache degli oggetti

associata all'OutputStream il garbage collector non può recuperare memoria relativa agli oggetti

scritti sullo stream trade off tra convenienza e semplicità e performance

• Se la performance è un obiettivo primario della applicazione, allora occorre personalizzare il protocollo di serializzazione mediante l'implementazione della interfaccia Externalizable

public void writeExternal(ObjectOutput out) throws IOException;

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

Page 45: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 45

INVIO OGGETTI SU STREAM

Per inviare oggetti su connessioni TCP

• associare i filtri ObjectInputStream/ObjectOutputStream agli stream di bytes associati al socket e restituiti da getInputStream/getOutputStream

• inviare/ricevere degli oggetti sullo/dallo stream avviene mediante scritture/letture sullo stream – writeObject– ReadObject

• i metodi precedenti implementano la serializzazione di un oggetto (discussa nella seconda parte della lezione)

Page 46: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 46

INVIO DI OGGETTI

import java.io.*;public class Studente implements Serializable {private int matricola;private String nome, cognome, corsoDiLaurea;public Studente(int matricola, String nome, String cognome,

String corsoDiLaurea) {this.matricola = matricola; this.nome = nome; this.cognome = cognome; this.corsoDiLaurea = corsoDiLaurea;}

public int getMatricola () { return matricola; }public String getNome () { return nome; }public String getCognome () { return cognome; }public String getCorsoDiLaurea () { return corsoDiLaurea; } }

Page 47: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 47

INVIO DI OGGETTI SU STREMS

import java.io.*; import java.net.*;public class Server {public static void main (String args[]) {try { ServerSocket server = new ServerSocket (3575);

Socket clientsocket = server.accept(); ObjectOutputStream output = new ObjectOutputStream (clientsocket.getOutputStream ());

output.writeObject("<Welcome>");Studente studente = new Studente

(14520,"Mario","Rosso","Informatica");output.writeObject(studente); output.writeObject("<Goodbye>");clientsocket.close();server.close();} catch (Exception e) { } } }

Page 48: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 48

COME CHIUDERE UNO STREAM

public class Client { public static void main (String args[ ]) {

try {Socket socket = new Socket ("localhost",3575);

ObjectInputStream input=newObjectInputStream(socket.getInputStream());

String beginMessage = (String) input.readObject();

System.out.println (beginMessage);

Studente studente = (Studente) input.readObject();

System.out.print (studente.getMatricola()+" - ");

System.out.print (studente.getNome()+""+studente.getCognome()+"- ");

System.out.print (studente.getCorsoDiLaurea()+"\n");

String endMessage = (String)input.readObject();

System.out.println (endMessage); socket.close();}

catch (Exception e) { System.out.println (e); } } }

Page 49: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 49

INVIO DI OGGETTI SU STREAMS

Stampa prodotta lato Client

<Welcome>

14520 - Mario Rossi - Informatica

<Goodbye>

Page 50: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 50

CHIUSURA DI STREAMS

import java.net.*; import java.io.*; import java.util.*;public class closer {

public static void main(String args[])throws Exception{InetAddress ia = InetAddress.getByName("localhost");Socket out =new Socket(ia,2500);OutputStream outs= out.getOutputStream();ObjectOutputStream oos = new ObjectOutputStream(outs);Date d= new Date();oos.writeObject(d);out.shutdownOutput();}

}

Page 51: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 51

CHIUSURA DI STREAMS

import java.net.*; import java.io.*; import java.util.*;public class server {public static void main (String args[]) throws Exception

{ServerSocket ss = new ServerSocket(2500);Socket s=ss.accept();InputStream is = s.getInputStream();ObjectInputStream ois = new ObjectInputStream(is);boolean go=true;while (go){try{ Date d =(Date) ois.readObject();

System.out.println(d);} catch (IOException e) {System.out.println(e); go=false; }}}}

Page 52: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 52

ASTA ELETTRONICA

Sviluppare un programma client server per il supporto di un'asta

elettronica. Ogni client possiede un budget massimo B da investire.

Il client può richiedere al server il valore V della migliore offerta

pervenuta fino ad un certo istante e decidere se abbandonare l'asta,

oppure rilanciare. Se il valore ricevuto dal server supera B, l'utente

abbandona l'asta, dopo aver avvertito il server. Altrimenti, il client rilancia,

inviando al server un valore maggiore di V.

Il server invia ai client che lo richiedono il valore della migliore offerta

ricevuta fino ad un certo momento e riceve dai client le richieste di

rilancio. Per ogni richiesta di rilancio, il server notifica al client se tale

offerta può essere accettata (nessuno ha offerto di più nel frattempo),

oppure è rifiutata.

Page 53: Lezione n.6 LPR Informatica Applicata Serializzazione JAVApages.di.unipi.it/ricci/28-03-13-Serialization.pdf · JAVA Serializzation Laura Ricci 1 Lezione n.6 LPR Informatica Applicata

Dipartimento di InformaticaUniversità degli studi di Pisa

JAVASerializzation

Laura Ricci 53

ASTA ELETTRONICA

Il server deve attivare un thread diverso per ogni client che intende

partecipare all'asta.

La comunicazione tra clients e server deve avvenire mediante socket

TCP. Sviluppare due diverse versioni del programma che utilizzino,

rispettivamente:

la serializzazione offerta da JAVA in modo da scambiare oggetti tramite

ule connessione TCP

una codifica testuale dei messaggi spediti tra client e sever