Friday, 6 July 2012

java.io.NotSerializableException in Java

Serialization is the process of saving an object state in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form.The object can be restored (Deserialization) at a later time, and even a later location. With persistence, we can move an object from one computer to another, and have it maintain its state.

There are two rules concerning persistent objects:

Rule 1: The object to be persisted must implement the marker interface java.io.Serializable or java.io.Externalizable or inherit that implementation from its object hierarchy.

Rule 2: The object to be persisted must mark all nonserializable fields transient.

If you are trying to serialize an object which does't follow the above rules, the method used for storing the object ObjectOutputStream.writeObject(Object obj) throws java.io.NotSerializableException.

See the examples given below

Example: Class does't implement the java.io.Serializable interface.


In this example we are trying to serialize an Employee object which does't implement the java.io.Serializable or java.io.Externalizable.

package serialize;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Serialization {

 /**
  * @param args
  * @throws ClassNotFoundException
  **/
 public static void main(String[] args) throws ClassNotFoundException {

  ObjectOutputStream out = null;
  try {
   out = new ObjectOutputStream(new FileOutputStream("employee.ser"));

   /** Create one Employee object to serialise **/

   Employee emp = new Employee("John", 12345, "Banking");

   /** Serialise the object emp and write to file employee.ser **/

   out.writeObject(emp);

  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    out.close();

   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

}

/**Non-serializable class**/

class Employee {

 int empno;
 String dept;

 public Employee(String empName, int empno, String dept) {
  this.empno = empno;
  this.dept = dept;
 }

 public Employee() {

 }

 /** Override the toString method to print object fields **/

 public String toString() {
  return ("Employee No =" + empno + " & Department =" + dept);
 }

}
The output will be


java.io.NotSerializableException: serialize.Employee
 at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
 at serialize.CustomSerialization.main(CustomSerialization.java:25)

Example: Class contains non-serializable fields.


In this example we are trying to serialize a Room object which contains a non-serializable Fan object reference.

package serialize;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

class Serialization {

 /**
  * @param args
  * @throws ClassNotFoundException
  **/
 public static void main(String[] args) throws ClassNotFoundException {

  ObjectOutputStream out = null;
  try {
   out = new ObjectOutputStream(new FileOutputStream("room.ser"));

   /** Create one Room object to serialise **/

   Fan f = new Fan("Usha", 2000);
   Room room100 = new Room(100, f);

   /** Serialise the object room100 and write to file room.ser **/

   out.writeObject(room100);

  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    out.close();

   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

}

class Fan {
 String brand;
 int price;

 public Fan(String brand, int price) {
  this.brand = brand;
  this.price = price;
 }

 public String toString() {
  return ("brand =" + brand + " & Price =" + price);
 }
}

class Room implements Serializable {

 int roomNo;
 Fan fan;  //non-serializable field

 public Room(int roomNo, Fan fan) {
  this.roomNo = roomNo;
  this.fan = fan;
 }

 public Room() {

 }

 /** Override the toString method to print object fields **/

 public String toString() {
  return ("Room No =" + roomNo + " & Fan =" + fan);
 }

}

The output will be

java.io.NotSerializableException: serialize.Fan
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at serialize.Serialization.main(Serialization.java:28)

The above exception can be resolved in two ways

Either declare the Fan object reference as 'transient' or make Fan class as serializable by implementing the java.io.Serializable interface.

No comments:

Post a Comment