exceptions

java.io.NotSerializableException – How to solve Not Serializable Exception

In this tutorial we will discuss about NotSerializableException in Java. The exception is thrown when an instance of a class must implement the Serializable interface. The exception is thrown by either the serialization runtime, or by the instance of the class. The argument of the NotSerializableException is the name of the class.

The NotSerializableException class extends the ObjectStreamException class, which is defined as the superclass of all exceptions specific to Object Stream classes. Also, the ObjectStreamException class extends the IOException which signals that an I/O exception has occurred.

Finally, the NotSerializableException exists since the 1.1 version of the Java Development Kit (JDK).

The Structure of NotSerializableException

Constructors

  • NotSerializableException()
  • Creates an instance of the NotSerializableException class.

  • NotSerializableException(String s)
  • Creates an instance of the NotSerializableException class, using the specified string as message. The string argument indicates the name of the class that threw the error.

The NotSerializableException in Java

To begin with, the NotSerializableException can be thrown when a class does not implement the Serializable interface. A sample example is described below:

Pair.java:

public class Pair {
	/**
	 * The key (left) part of the pair.
	 */
	private K key;
	
	/**
	 * The value (right) part of the pair.
	 */
	private V value;
	
	public Pair(K key, V value) {
		this.key = key;
		this.value = value;
	}
	
	/**
	 * 
	 * @return, the pair's key.
	 */
	public K getKey() {
		return this.key;
	}
	
	/**
	 * 
	 * @return, the pair's value.
	 */
	public V getValue() {
		return this.value;
	}
	
	/**
	 * Tests if an instance of the Pair class is equal to a specified Object.
	 */
	@Override
	public boolean equals(Object o) {
		if(o instanceof Pair) {
			Pair pair = (Pair) o;
			return (this.key == pair.key && this.value == pair.value);
		}
		else
			return false;
	}
	
	/**
	 * Creates a String representation of the Pair class.
	 */
	@Override
	public String toString() {
		return "Pair: ";
	}
}

In this file, we defined the Pair class, as a Java template, which consists of two fields, key and value. Also, we defined the following methods:

  • K getKey()
  • Returns the key of the pair.

  • V getValue()
  • Returns the value of the pair.

  • boolean equals(Object o)
  • Checks whether the specified object equals to this pair.

  • String toString()
  • Returns a String representation of the Pair class.

Serializer.java:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public final class Serializer {
	/**
	 * Converts an Object to a byte array.
	 * 
	 * @param object, the Object to serialize.
	 * @return, the byte array that stores the serialized object.
	 */
	public static  byte[] serialize(T object) {

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutput out = null;
		try {
			out = new ObjectOutputStream(bos);
			out.writeObject(object);

			byte[] byteArray = bos.toByteArray();
			return byteArray;

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

		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException ex) {
			}
			try {
				bos.close();
			} catch (IOException ex) {
			}
		}

	}

	/**
	 * Converts a byte array to an Object.
	 * 
	 * @param byteArray, a byte array that represents a serialized Object.
	 * @return, an instance of the Object class.
	 */
	public static Object deserialize(byte[] byteArray) {
		ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
		ObjectInput in = null;
		try {
			in = new ObjectInputStream(bis);
			Object o = in.readObject();
			return o;

		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				bis.close();
			} catch (IOException ex) {
			}
			try {
				if (in != null)
					in.close();
			} catch (IOException ex) {
			}
		}
	}
}

In this file, we defined the Serializer class, which contains the following two static methods:

  • static byte[] serialize(T object)
  • Serializes the specified object in a byte array.

  • static Object deserialize(byte[] byteArray)
  • Deserializes the specified byte array to an instance of the Object class.

NotSerializableExceptionExample.java:

public class NotSerializableExceptionExample {
	public static void main(String[] args) {
		Pair pair = new Pair("Key1", 1);
		
		System.out.println("Trying to serialize the following object: " + pair);
		Serializer.serialize(pair); // This statement throws a NotSerializableException
	}
}

In this file, we defined the main method of our application that aims to serialize an instance of the Pair class. However, the Pair class does not implement the Serializable interface and thus, the NotSerializableException is thrown.

A sample execution is shown below:

Trying to serialize the following object: Pair: 
java.io.NotSerializableException: main.java.Pair
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at main.java.Serializer.serialize(Serializer.java:24)
	at main.java.NotSerializableExceptionExample.main(NotSerializableExceptionExample.java:8)

Also, the NotSerializableException can be thrown when a class that implements the Serializable interface contains fields that are not serializable:

SerializableClass.java:

import java.io.Serializable;

public class SerializableClass implements Serializable {
	private static final long serialVersionUID = 1420672609912364060L;
	private Pair pair = null;
	
	public SerializableClass(String key, Integer value) {
		this.pair = new Pair(key, value);
	}
	
	@Override
	public String toString() {
		return pair.toString();
	}
}

In this file, we defined the SerializableClass that contains a Pair field. The SerializableClass implements the Serializable interface, but it refers to the Pair class which doesn’t.

NotSerializableExceptionExample_v2.java:

public class NotSerializableExceptionExample_v2 {
	public static void main(String[] args) {
		SerializableClass sClass = new SerializableClass("Key1", 1);
		
		System.out.println("Trying to serialize the following object: " + sClass);
		Serializer.serialize(sClass); // This statement throws a NotSerializableException
	}
}

A sample execution is shown below:

Trying to serialize the following object: Pair: 
java.io.NotSerializableException: main.java.Pair
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at main.java.Serializer.serialize(Serializer.java:24)
	at main.java.NotSerializableExceptionExample_v2.main(NotSerializableExceptionExample_v2.java:8)

How to deal with the NotSerializableException

  • The simplest solution is to find the class that throws the exception and make it implement the Serializable interface. However, this may not be feasible if the class that throws the exception belongs to a third-party library.
  • In case the class refers to non-serializable objects and these objects should not be serialized, then, you can declare these objects as transient. Once a field of a class is declared as transient, then, it is ignored by the serializable runtime. For example:
    TransientExample.java:

    import java.io.Serializable;
    
    public class TransientExample implements Serializable {
    	private static final long serialVersionUID = 6128016096756071380L;
    	private transient Pair pair = null;
    	
    	public TransientExample(String key, Integer value) {
    		this.pair = new Pair(key, value);
    	}
    	
    	@Override
    	public String toString() {
    		return pair.toString();
    	}
    }
    

    In this file, we defined the TransientExample that contains a Pair field. The TransientExample implements the Serializable interface, but it refers to the Pair class which doesn’t. However, the reference is declared as transient and thus, the object can be serialized normally:

    NotSerializableExceptionExample_v3.java:

    public class NotSerializableExceptionExample_v3 {
    	public static void main(String[] args) {
    		TransientExample ex = new TransientExample("key", 1);
    		
    		System.out.println("Trying to serialize the following object: " + ex);
    		Serializer.serialize(ex);
    		System.out.println("The " + ex + " object was successfully serialized!");
    	}
    }
    

    A sample execution is shown below:

    Trying to serialize the following object: Pair: 
    The Pair:  object was successfully serialized!
    

Download the Eclipse Project

The Eclipse project of this example: NotSerializableExceptionExample.zip.

 
This was a tutorial about the NotSerializableException in Java.

Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Aarti Kumar
Aarti Kumar
6 years ago

Thanks for the solution… it helped me resolve my issue !!!!!

Back to top button