Serialization in Java Critical for Java network abilities Jeslie Chermak ( [email_address] )
What is “serialization”? Serialization is the (reversible) encoding of objects, and the objects reachable in them, into a stream of bytes. It is by no means unique to Java: http://en.wikipedia.org/wiki/Serialization This talk is based on information from http://download.oracle.com/javase/tutorial/essential/io/objectstreams.html
Why Should I Use It? BASIS FOR ALL PERSISTENCE IN JAVA ! Simple to add to most classes. Allows for easy extension. Handles versioning.
Simple Class Create a new class in package com.jcc.training.generics Class will implement a traditional “stack” containing Integer s Only methods are push , pop , top Allow NULL s in stack
Java 1.4 Implementation package com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack { private final List stack = new ArrayList(); public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return (Integer) this . stack .get( this . stack .size() - 1); } public Integer pop() { final Integer value = this .top(); this . stack .remove( this . stack .size() - 1); return value; } }
WIBNIF Problem: How do we make this class serializable? Solution: Use a special “marker” interface -- Serializable
Java 1.4 Implementation package com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack implements java.io.Serializable { // marker interface private final List stack = new ArrayList(); public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return (Integer) this . stack .get( this . stack .size() - 1); } public Integer pop() { final Integer value = this .top(); this . stack .remove( this . stack .size() - 1); return value; } }
WIBNIF Problem: Java has evolved since 1.4 Solution: Serialization has been present since initial public release (1.0.2) -- it is a core feature of the language implementation
Java 5 with Generics package com.jcc.training.generics; import java.io.Serializable; // missing earlier import java.util.ArrayList; import java.util.List; public class Stack implements Serializable { // marker interface private final List<Integer> stack = new ArrayList<Integer>(); // field typed! public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return this . stack .get( this . stack .size() - 1); // no cast! } public Integer pop() { final int value = this .top(); // OOPS! this . stack .remove( this . stack .size() - 1); return value; } }
WIBNIF Problem: class es evolve over time Solution: introduce a version UID to capture “real” changes
Improved and Versioned package com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack<E> implements java.io.Serializable { // class typed! private static final long serialVersionUID = 1L; // we specified private final List<E> stack = new ArrayList<E>(); // typed by class public void push( final E value) { // typed by class this . stack .add(value); // NULL allowed! } public E top() { // typed by class if ( this . stack .isEmpty()) throw new IllegalStateException(); return this . stack .get( this . stack .size() - 1); } public E pop() { // typed by class final E value = this .top(); // typed by class this . stack .remove( this . stack .size() - 1); return value; } }
WIBNIF Problem: some code lacks the UID Solution: define default UID to match that normally built in a class -- serialver program
Good News Most (all?) IDEs provide a serialver hook Writing simple objects is easy Reading objects is comparable
Object I/O Writing: public void writeIt( OutputStream os, Foo foo) { ObjectOutputStream oos = new ObjectOutputStream (os); oos.writeObject(foo); oos.close(); } Reading: public Foo readIt( InputStream is) { ObjectInputStream ois = new ObjectInputStream (is); Foo foo = ( Foo ) ois.readObject(); ois.close(); return foo; }
WIBNIF Problem: not every field should be serialized Solution: transient fields Problem: static fields are the same for each object instance Solution: they are not written by default
Bad News Default readObject() and writeObject() methods may not properly handle objects with transient and/or static fields
Good News Object.readObject() and Object.writeObject() methods (used in default handling) are overloadable: private void readObject( ObjectInputStream ) throws IOException, ClassNotFoundException; private void writeObject( ObjectOutputStream ) throws IOException;
Better News When default handling is insufficient, use the Externalizable interface instead of Serializable and implement readExternal() and writeExternal() -- a lot more work for total control of serialization
Going Further … Java tutorials: http://download.oracle.com/javase/tutorial/index.html Serialization in depth w/examples: http://download.oracle.com/javase/7/docs/technotes/guides/serialization/index.html Object streams: http://download.oracle.com/javase/tutorial/essential/io/objectstreams.html Google “java serialization”

Java Serialization

  • 1.
    Serialization in JavaCritical for Java network abilities Jeslie Chermak ( [email_address] )
  • 2.
    What is “serialization”?Serialization is the (reversible) encoding of objects, and the objects reachable in them, into a stream of bytes. It is by no means unique to Java: http://en.wikipedia.org/wiki/Serialization This talk is based on information from http://download.oracle.com/javase/tutorial/essential/io/objectstreams.html
  • 3.
    Why Should IUse It? BASIS FOR ALL PERSISTENCE IN JAVA ! Simple to add to most classes. Allows for easy extension. Handles versioning.
  • 4.
    Simple Class Createa new class in package com.jcc.training.generics Class will implement a traditional “stack” containing Integer s Only methods are push , pop , top Allow NULL s in stack
  • 5.
    Java 1.4 Implementationpackage com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack { private final List stack = new ArrayList(); public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return (Integer) this . stack .get( this . stack .size() - 1); } public Integer pop() { final Integer value = this .top(); this . stack .remove( this . stack .size() - 1); return value; } }
  • 6.
    WIBNIF Problem: Howdo we make this class serializable? Solution: Use a special “marker” interface -- Serializable
  • 7.
    Java 1.4 Implementationpackage com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack implements java.io.Serializable { // marker interface private final List stack = new ArrayList(); public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return (Integer) this . stack .get( this . stack .size() - 1); } public Integer pop() { final Integer value = this .top(); this . stack .remove( this . stack .size() - 1); return value; } }
  • 8.
    WIBNIF Problem: Javahas evolved since 1.4 Solution: Serialization has been present since initial public release (1.0.2) -- it is a core feature of the language implementation
  • 9.
    Java 5 withGenerics package com.jcc.training.generics; import java.io.Serializable; // missing earlier import java.util.ArrayList; import java.util.List; public class Stack implements Serializable { // marker interface private final List<Integer> stack = new ArrayList<Integer>(); // field typed! public void push( final Integer value) { this . stack .add(value); // NULL allowed! } public Integer top() { if ( this . stack .isEmpty()) throw new IllegalStateException(); return this . stack .get( this . stack .size() - 1); // no cast! } public Integer pop() { final int value = this .top(); // OOPS! this . stack .remove( this . stack .size() - 1); return value; } }
  • 10.
    WIBNIF Problem: class es evolve over time Solution: introduce a version UID to capture “real” changes
  • 11.
    Improved and Versioned package com.jcc.training.generics; import java.util.ArrayList; import java.util.List; public class Stack<E> implements java.io.Serializable { // class typed! private static final long serialVersionUID = 1L; // we specified private final List<E> stack = new ArrayList<E>(); // typed by class public void push( final E value) { // typed by class this . stack .add(value); // NULL allowed! } public E top() { // typed by class if ( this . stack .isEmpty()) throw new IllegalStateException(); return this . stack .get( this . stack .size() - 1); } public E pop() { // typed by class final E value = this .top(); // typed by class this . stack .remove( this . stack .size() - 1); return value; } }
  • 12.
    WIBNIF Problem: somecode lacks the UID Solution: define default UID to match that normally built in a class -- serialver program
  • 13.
    Good News Most(all?) IDEs provide a serialver hook Writing simple objects is easy Reading objects is comparable
  • 14.
    Object I/O Writing:public void writeIt( OutputStream os, Foo foo) { ObjectOutputStream oos = new ObjectOutputStream (os); oos.writeObject(foo); oos.close(); } Reading: public Foo readIt( InputStream is) { ObjectInputStream ois = new ObjectInputStream (is); Foo foo = ( Foo ) ois.readObject(); ois.close(); return foo; }
  • 15.
    WIBNIF Problem: notevery field should be serialized Solution: transient fields Problem: static fields are the same for each object instance Solution: they are not written by default
  • 16.
    Bad News Default readObject() and writeObject() methods may not properly handle objects with transient and/or static fields
  • 17.
    Good News Object.readObject() and Object.writeObject() methods (used in default handling) are overloadable: private void readObject( ObjectInputStream ) throws IOException, ClassNotFoundException; private void writeObject( ObjectOutputStream ) throws IOException;
  • 18.
    Better News Whendefault handling is insufficient, use the Externalizable interface instead of Serializable and implement readExternal() and writeExternal() -- a lot more work for total control of serialization
  • 19.
    Going Further …Java tutorials: http://download.oracle.com/javase/tutorial/index.html Serialization in depth w/examples: http://download.oracle.com/javase/7/docs/technotes/guides/serialization/index.html Object streams: http://download.oracle.com/javase/tutorial/essential/io/objectstreams.html Google “java serialization”

Editor's Notes

  • #2 GOOD AFTERNOON MY NAME IS …
  • #4 WHY USE THIS? I’M PRODUCTIVE AND COMFORTABLE AS IS.
  • #5 WE’RE GOING TO MAKE A SIMPLE CLASS TO ILLUSTRATE HOW EASY SERIALIZATION CAN BE.
  • #6 WE START WITH A PRE-JAVA 5 VERSION. WE’LL USE JAVA 1.4 NOTE THAT OUR EXAMPLE LACKS JAVADOC COMMENTS. DON’T DO THIS IN ANY OF YOUR OWN CODE!
  • #7 OUR CODE WAS NOT BUILT TO BE SAVEABLE – WHAT DO I CHANGE … ?
  • #8 … WE CHANGED JUST ONE (1) LINE!
  • #9 WHAT ABOUT LEGACY CODE? HOW HARD TO UPGRADE?
  • #10 WE’LL REWIRTE OUR EXAMPLE FOR JAVA 5 BUT NOTICE THE CHANGE REQUIRED FOR SERIALIZATION (NONE!)
  • #11 WHAT ABOUT NEW CODE EVOLUTION?
  • #12 MUCH FANCIER JAVA GENERIC CODE WITH A “Unique ID”
  • #13 OKAY, BUT WHAT ABOUT LEGACY CODE WITHOUT THE UID?
  • #15 HOW “EASY” IS “EASY”?
  • #16 IS EVERYTHING SAVED? CAN’T WE CONTROL WHAT WE KEEP?
  • #20 THIS WAS JUST AN INTRODUCTION. THERE ARE SOME VERY USEFUL TOPICS WE HAVE NOT EVEN TOUCHED ON.