-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
1.4.2
-
x86
-
windows_2000
FULL PRODUCT VERSION :
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
De-serializing an instance of this class throws a NullPointerException:
import java.io.*;
import java.util.*;
private class MyClass implements Serializable
{
private String m_name = "anything";
private Set m_set = new HashSet ();
public MyClass ()
{
m_set.add (this);
}
public int hashCode ()
{
return m_name.hashCode ();
}
}
I think this happens because the VM attempts to de-serialize m_set first and in doing so calls hashCode() on each of its members. However, the instance of MyClass, contained in m_set, has not yet been fully de-serialized since this involves de-serializing m_set first. Thus, m_name is still null when hashCode() is called, causing the Exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Serialize and then De-serialize an instance of MyClass using the program provided.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was expecting to see MyClass De-serialize completely and wihout error.
ACTUAL -
A NullPointerException was thrown from the line:
return m_name.hashCode ();
m_name was null.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
at com.bentley.test.MyClass.hashCode(TestSerialization.java:67)
at java.util.HashMap.hash(HashMap.java:261)
at java.util.HashMap.put(HashMap.java:379)
at java.util.HashSet.readObject(HashSet.java:277)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:838)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
at com.bentley.test.TestSerialization.input(TestSerialization.java:46)
at com.bentley.test.TestSerialization.main(TestSerialization.java:23)
Exception in thread "main"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*--------------------------------------------------------------------------------------+
|
| $RCSfile: TestSerialization.java,v $
| $Revision: 1.0 $
| $Date: 2004/08/24 14:31:30 $
|
| $Copyright: (c) 2004 Bentley Systems, Incorporated. All rights reserved. $
|
+--------------------------------------------------------------------------------------*/
package com.bentley.test;
import java.io.*;
import java.util.*;
public class TestSerialization
{
public static void main (String[] args) throws Exception
{
MyClass obj = new MyClass ();
byte[] serialized = output (obj);
Serializable deserialized = input (serialized);
}
public static byte[] output (Serializable obj) throws Exception
{
ByteArrayOutputStream obytes = new ByteArrayOutputStream ();
ObjectOutputStream ostream = new ObjectOutputStream (obytes);
ostream.writeObject (obj);
ostream.flush ();
byte[] bytes = obytes.toByteArray ();
obytes.close ();
ostream.close ();
return bytes;
}
public static Serializable input (byte[] bytes) throws Exception
{
ByteArrayInputStream ibytes = new ByteArrayInputStream (bytes);
ObjectInputStream istream = new ObjectInputStream (ibytes);
Serializable obj = (Serializable)istream.readObject ();
ibytes.close ();
istream.close ();
return obj;
}
}
class MyClass implements Serializable
{
private String m_name = "anything";
private Set m_set = new HashSet ();
public MyClass ()
{
m_set.add (this);
}
public int hashCode ()
{
return m_name.hashCode ();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found a good one yet, other than to avoid overriding the hashCode method.
###@###.### 2004-12-14 10:26:52 GMT
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
De-serializing an instance of this class throws a NullPointerException:
import java.io.*;
import java.util.*;
private class MyClass implements Serializable
{
private String m_name = "anything";
private Set m_set = new HashSet ();
public MyClass ()
{
m_set.add (this);
}
public int hashCode ()
{
return m_name.hashCode ();
}
}
I think this happens because the VM attempts to de-serialize m_set first and in doing so calls hashCode() on each of its members. However, the instance of MyClass, contained in m_set, has not yet been fully de-serialized since this involves de-serializing m_set first. Thus, m_name is still null when hashCode() is called, causing the Exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Serialize and then De-serialize an instance of MyClass using the program provided.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I was expecting to see MyClass De-serialize completely and wihout error.
ACTUAL -
A NullPointerException was thrown from the line:
return m_name.hashCode ();
m_name was null.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
at com.bentley.test.MyClass.hashCode(TestSerialization.java:67)
at java.util.HashMap.hash(HashMap.java:261)
at java.util.HashMap.put(HashMap.java:379)
at java.util.HashSet.readObject(HashSet.java:277)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:838)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
at com.bentley.test.TestSerialization.input(TestSerialization.java:46)
at com.bentley.test.TestSerialization.main(TestSerialization.java:23)
Exception in thread "main"
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*--------------------------------------------------------------------------------------+
|
| $RCSfile: TestSerialization.java,v $
| $Revision: 1.0 $
| $Date: 2004/08/24 14:31:30 $
|
| $Copyright: (c) 2004 Bentley Systems, Incorporated. All rights reserved. $
|
+--------------------------------------------------------------------------------------*/
package com.bentley.test;
import java.io.*;
import java.util.*;
public class TestSerialization
{
public static void main (String[] args) throws Exception
{
MyClass obj = new MyClass ();
byte[] serialized = output (obj);
Serializable deserialized = input (serialized);
}
public static byte[] output (Serializable obj) throws Exception
{
ByteArrayOutputStream obytes = new ByteArrayOutputStream ();
ObjectOutputStream ostream = new ObjectOutputStream (obytes);
ostream.writeObject (obj);
ostream.flush ();
byte[] bytes = obytes.toByteArray ();
obytes.close ();
ostream.close ();
return bytes;
}
public static Serializable input (byte[] bytes) throws Exception
{
ByteArrayInputStream ibytes = new ByteArrayInputStream (bytes);
ObjectInputStream istream = new ObjectInputStream (ibytes);
Serializable obj = (Serializable)istream.readObject ();
ibytes.close ();
istream.close ();
return obj;
}
}
class MyClass implements Serializable
{
private String m_name = "anything";
private Set m_set = new HashSet ();
public MyClass ()
{
m_set.add (this);
}
public int hashCode ()
{
return m_name.hashCode ();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not found a good one yet, other than to avoid overriding the hashCode method.
###@###.### 2004-12-14 10:26:52 GMT
- duplicates
-
JDK-8249598 (de)serialization circular references with HashSets fail in .hashCode()
-
- Closed
-
- relates to
-
JDK-4957674 Hash entries placed into wrong buckets during deserialization
-
- Open
-
-
JDK-8201131 Deserialization fails for cyclic object graphs, superclassing, and HashSet
-
- Open
-
-
JDK-8024931 Deserialization fails with cyclic object graph and serial proxy
-
- Open
-