OptionalDataException:
This java.io.OptionalDataException is usually thrown when we try to deserialize an object
from the stream. Let's see in this post what are the reasons for this exception to be thrown while deserializing an object.
There are two reasons for this exception to be thrown.They are
1.When we try to deserialize a primitive type(like int,string,char,float,double) using the readObject() method of the DataInput interface then this exception will be thrown.
2.When we try to deserialize an object which is no longer available in the stream using the custom readObject() method(which is the class-defined readObject() method).
Here in this post i have presented you two examples which explains you why this exception is thrown because of this two reasons.
Reason1:
"Deserializing a primitive type data"
Have a look at the following program and its output to understand why this exception is thrown because of this reason.
Program:
Students.java:
import java.util.*;
import java.io.*;
class Students implements Serializable
{
String name;
int Regno;
}
Optional.java:
import java.io.*;
import java.lang.*;
import java.util.*;
class Optional extends Students
{
public static void main(String args[])
{
try
{
Optional op1=new Optional();
op1.name="Ganesh";
op1.Regno=80;
Optional op2=new Optional();
op2.name="Hari";
op2.Regno=90;
int a=10;
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("serial.dat"));
os.writeObject(op1);
os.writeInt(a);
os.writeObject(op2);
ObjectInputStream is=new ObjectInputStream(new FileInputStream("serial.dat"));
Optional p=(Optional)is.readObject();
Optional s=(Optional)is.readObject();
System.out.println(s.name);
System.out.println(s.Regno);
System.out.println(p.name);
System.out.println(p.Regno);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Output:
java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at Optional.main(Optional.java:24)
The temp batch file is supposed to be deleted hence...
The batch file cannot be found.
Process returned 0 (0x0) execution time : 0.243 s
Press any key to continue.
If you look at the highlighted statements in the above program,you can able to infer that. First i have stored an object op1 of Optional type in the stream and then i stored the primitive type(int a) in the stream.
But while deserializing the objects, I tried to deserialize both the objects as of type (Optional) Since the second object is of int (primitive) type this OptionalDataException is thrown. If you try the reverse case i.e, deserializing both the objects as of primitive type then EOF file exception will be thrown.
Here you have to remember one thing that "you should deserialize the objects in the same order in which you have serialized the object".
Reason 2:
"Trying to read the unavailable object from the stream using the custom class-defined readObject() method".
Look at the program below to understand how i have used the custom readObject() method to deserialize the objects from the stream.
Program:
Ram.java
import java.io.*;
class Ram implements Serializable
{
String name;
int mark;
}
Serialize.java
class Serialize
{
public static void main(String args[])
{
Primit p=new Primit();
p.execute();
}
}
Primit.java
import java.io.*;
import java.util.*;
import java.lang.*;
class Primit implements Serializable
{
Ram r=new Ram();
Ram r1=new Ram();
Ram r2=new Ram();
public void execute()
{
try
{
r.name="ram";
r.mark=90;
r1.name="ram1";
r1.mark=80;
r2.name="ram2";
r2.mark=70;
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("primit.dat"));
os.writeObject(this);
ObjectInputStream is=new ObjectInputStream(new FileInputStream("primit.dat"));
is.readObject();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void writeObject(ObjectOutputStream out)throws IOException
{
System.out.println("I am inside writeObject()");
out.defaultWriteObject();
out.writeObject(r);// Object no:1
out.writeObject(r1);// Object no:2
out.writeObject(r2);// Object no:3
}
private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException
{
System.out.println("I am inside readObject()");
in.defaultReadObject();
Ram s=(Ram)in.readObject();//Object no:1
System.out.println(s.name);
Ram s1=(Ram)in.readObject();// Object no:2
System.out.println(s1.name);
Ram s2=(Ram)in.readObject();// Object no:3
System.out.println(s2.name);
Ram s3=(Ram)in.readObject();// Object no:4
}
}
Output:
I am inside writeObject()
I am inside readObject()
ram
ram1
ram2
java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at Primit.readObject(Primit.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at Primit.execute(Primit.java:24)
at Serialize.main(Serialize.java:6)
If you look at the highlighted statements in the above program you can able to infer one thing that i have serialized only three objects but i have tried to deserialize Four objects.Since the fourth object is not available in the stream this exception is thrown at run-time.