The term serialization

All terms are aptly given name after careful consideration and serialization is no exception. When you are serializing an object, you are representing the object information in a serial form. A serial form is the one which occurs in series one after another.

The connection between object binary state and the term serialization are very closely related which can be understood from following statements:

Initially there was a need to persist or send the object states from one physical machine to another over the network. This object state storage/transmission had to be such that the binary data is stored or sent in terms of bytes or network packets and then assembled at the other end. Since the binary data is sent as one byte after another (or one packet after another), the term serialization is used for this process.

How to perform Serialization

The Serialization API was added from JDK 1.1 onwards with the introduction of java.io.Serializable interface. This interface is marker interface which means when you implement this interface, you needn’t override any method. In fact, this interface acts like a check for JVM to ensure that the program (as well programmer) knows what he is going to do.

The real functionality of serializing the objects into streams is implemented by Java through the ObjectInputStream and ObjectOutputStream classes.

The following sample code shows how to perform serialization in Java.

package com.example;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class SuperTest {

    int a = 10;
}

public class Test extends SuperTest implements Serializable{

    int b = 20;

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

        File f = new File("c://serial.txt");
        Test t = new Test();
        FileOutputStream fos = new FileOutputStream(f);
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        FileInputStream fis = new FileInputStream(f);
        ObjectInputStream ois = new ObjectInputStream(fis);

        oos.writeObject(t);

        Test t1 = (Test)ois.readObject(); //This type cast is necessary
        System.out.println(t1.a +  " " + t1.b);

    }
}

Output :

10 20

Understanding the sample code

You may notice that a field named serialVersionUID has been defined in the above program. I have already written a tutorial on the importance of serialVersionUID in Java. Also since our serializable class is inheriting another class and thus inheriting some member variables from super class, the inherited member variables also take part in the serialization process.

Thus when a single object is serialized, the complete object graph (i.e. all objects reachable from that object) are serialized. This is required so as to re-construct the object when de-serialization operation is performed.

Note: There is no need for no-arg constructor in the Serializable class but there is a need for public no-arg constructor for an Externalizable class (a class which implements Externalizable interface). However, in case of Serializable, the first non-serializable super class must provide a public no argument constructor.

If I declare a private no-arg constructor and public one argument constructor in the above program, the object de-serialization process will fail with the error “java.io.InvalidClassException: com.example.Test; no valid constructor”

Object binary state

When seen using a hex reader, the binary object state in the above program will look like the following listing:

0000-0010: ac ed 00 05-73 72 00 10-63 6f 6d 2e-65 78 61 6d ….sr.. com.exam
0000-0020: 70 6c 65 2e-54 65 73 74-b7 2d 83 7d-24 fb c8 59 ple.Test .-.}$..Y
0000-002d: 02 00 01 49-00 01 62 78-70 00 00 00-14 …I..bx p….

All the object state including the serialversionUID is present in the above binary data. The meaning of each of the hex code in above text is out of scope for this tutorial.

Serialization Security Concerns

There are inherent security concerns with serialization process. When serializing an object, you are letting escape object information to the outside world. The object state is in memory when the program is running but as soon as you serialize the object, its state is exposed to outside world through the binary stream. Anyone with a hex editor can see the values of member variables of a serialized object.

Since Java has strict checks on memory to ensure security, letting go object state out could be a major concern for critical applications like Banking or Government. It is the responsibility of the developer to ensure that only the really required information is serialized as part of the object.

Some members of an object can be stopped from being serialized by the use of static and transient keywords. All the static (except serialVersionUID) and transient member variables of a class are not serialized as part of object state.

Uses of Serialization

Serialization can be used for multiple purposes and some of them are listed below:

1) Sending server side exceptions to the client side as with EJB (Enterprise Java Beans)
2) Performing a deep copy (deep cloning) operation.
3) Persisting the state of application when no network connection is available or before machine shutdown.
4) Passing normal object states from client side to server side as with Swing objects.

Serialization Tools

There are many tools which make use of serialization to provide different features. There are even some tools which make the serialization process simpler. Here is a list of some of the useful tools related to serialization:

  • JSerial : This one is my favorite as this tool makes use of Java reflection API in order to make the serialization operation faster. It is recommended to be used when you are facing performance issues with regard to serialization using ObjectInputStream and ObjectOutputStream.

  • Apache Commons SerializationUtils : This utility class has method to perform serialization, de-serialzation, cloning and I/O resource management using finally. The use of this helper class will definitely reduce burden on a serialization heavy application.

  • XML Encoder : An object can be serialized and de-serialized to/from XML format using the java.beans.XMLEncoder and java.beans.XMLDecoder classes. These classes make use of the fact that binary data can be part of an xml with encoding as base64. These two classes are in fact an alternative to java.io.ObjectInputStream and java.io.ObjectOutputStream. Once the object state is present in XML, you can easily parse it and get the binary data.

Our tutorial has touched almost all parts of serialization. I hope you enjoyed reading it and gained more insight into serialization API in Java.

Object Serialization in Java admin Core Java
The term serialization All terms are aptly given name after careful consideration and serialization is no exception. When you are serializing an object, you are representing the object information in a serial form. A serial form is the one which occurs in series one after another. The connection between object...
<h2>The term serialization</h2> All terms are aptly given name after careful consideration and serialization is no exception. When you are serializing an object, you are representing the object information in a serial form. A serial form is the one which occurs in series one after another. The connection between object binary state and the term serialization are very closely related which can be understood from following statements: Initially there was a need to persist or send the object states from one physical machine to another over the network. This object state storage/transmission had to be such that the <strong>binary data is stored or sent in terms of bytes or network packets</strong> and then assembled at the other end. Since the binary data is sent as one byte after another (or one packet after another), the term serialization is used for this process. <h2>How to perform Serialization</h2> The <strong>Serialization API was added from JDK 1.1 onwards</strong> with the introduction of java.io.Serializable interface. This interface is <a href="http://www.javaexperience.com/java-marker-interfaces/">marker interface</a> which means when you implement this interface, you needn't override any method. In fact, this interface acts like a check for JVM to ensure that the program (as well programmer) knows what he is going to do. The real functionality of serializing the objects into streams is implemented by Java through the ObjectInputStream and ObjectOutputStream classes. The following sample code shows how to perform serialization in Java. 1 Output : <blockquote>10 20</blockquote> <h2>Understanding the sample code</h2> You may notice that a field named serialVersionUID has been defined in the above program. I have already written a tutorial on the <a href="http://www.javaexperience.com/java-role-of-serialversionuid-in-serialization/">importance of serialVersionUID in Java</a>. Also since our serializable class is inheriting another class and thus inheriting some member variables from <a href="http://www.javaexperience.com/this-and-super-in-java/">super</a> class, the inherited member variables also take part in the serialization process. Thus when a single object is serialized, the complete object graph (i.e. all objects reachable from that object) are serialized. This is required so as to re-construct the object when de-serialization operation is performed. <strong>Note:</strong> There is no need for no-arg constructor in the Serializable class but there is a need for public no-arg constructor for an <a href="http://www.javaexperience.com/java-externalizable-vs-serializable-interfaces/">Externalizable class</a> (a class which implements Externalizable interface). However, in case of Serializable, <strong>the first non-serializable super class must provide a public no argument constructor</strong>. If I declare a private no-arg constructor and public one argument constructor in the above program, the object de-serialization process will fail with the error "java.io.InvalidClassException: com.example.Test; no valid constructor" <h2>Object binary state</h2> When seen using a hex reader, the binary object state in the above program will look like the following listing: <blockquote> 0000-0010: ac ed 00 05-73 72 00 10-63 6f 6d 2e-65 78 61 6d ....sr.. com.exam 0000-0020: 70 6c 65 2e-54 65 73 74-b7 2d 83 7d-24 fb c8 59 ple.Test .-.}$..Y 0000-002d: 02 00 01 49-00 01 62 78-70 00 00 00-14 ...I..bx p.... </blockquote> All the object state including the serialversionUID is present in the above binary data. The meaning of each of the hex code in above text is out of scope for this tutorial. <h2>Serialization Security Concerns</h2> There are inherent security concerns with serialization process. When serializing an object, you are letting escape object information to the outside world. The object state is in memory when the program is running but as soon as you serialize the object, its state is exposed to outside world through the binary stream. Anyone with a hex editor can see the values of member variables of a serialized object. Since Java has strict checks on memory to ensure security, letting go object state out could be a major concern for critical applications like Banking or Government. It is the responsibility of the developer to ensure that only the really required information is serialized as part of the object. Some members of an object can be stopped from being serialized by the use of static and transient keywords. All the static (except serialVersionUID) and transient member variables of a class are not serialized as part of object state. <h2>Uses of Serialization</h2> Serialization can be used for multiple purposes and some of them are listed below: 1) Sending server side exceptions to the client side as with EJB (Enterprise Java Beans) 2) Performing a deep copy (<a href="http://www.javaexperience.com/java-cloning-tutorial/">deep cloning</a>) operation. 3) Persisting the state of application when no network connection is available or before machine shutdown. 4) Passing normal object states from client side to server side as with Swing objects. <h2>Serialization Tools</h2> There are many tools which make use of serialization to provide different features. There are even some tools which make the serialization process simpler. Here is a list of some of the useful tools related to serialization: <ul> <li><a href="http://jserial.sourceforge.net/"><strong>JSerial</strong></a> : This one is my favorite as this tool makes use of Java reflection API in order to make the serialization operation faster. It is recommended to be used when you are facing performance issues with regard to serialization using ObjectInputStream and ObjectOutputStream. <br/> </li> <li><a href="http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/SerializationUtils.html"><strong>Apache Commons SerializationUtils</strong></a> : This utility class has method to perform serialization, de-serialzation, cloning and <a href="http://www.javaexperience.com/java-finally-executes-finally/">I/O resource management using finally</a>. The use of this helper class will definitely reduce burden on a serialization heavy application. <br/> </li> <li><a href="http://docs.oracle.com/javase/1.4.2/docs/api/java/beans/XMLEncoder.html"><strong>XML Encoder</strong></a> : An object can be serialized and de-serialized to/from XML format using the java.beans.XMLEncoder and java.beans.XMLDecoder classes. These classes make use of the fact that binary data can be part of an xml with encoding as base64. These two classes are in fact an alternative to java.io.ObjectInputStream and java.io.ObjectOutputStream. Once the object state is present in XML, you can easily parse it and get the binary data. <br/> </li> </ul> Our tutorial has touched almost all parts of serialization. I hope you enjoyed reading it and gained more insight into serialization API in Java.