-
Bug
-
Resolution: Duplicate
-
P4
-
8, 11.0.2, 15
-
x86_64
-
generic
ADDITIONAL SYSTEM INFORMATION :
Same issue with Java 1.8.0_151 and 11.0.1+13. I'm running the test from IntelliJ:
IntelliJ IDEA 2019.1 (Ultimate Edition)
Build #IU-191.6183.87, built on March 27, 2019
JRE: 1.8.0_202-release-1483-b39 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Linux 4.15.0-47-generic
A DESCRIPTION OF THE PROBLEM :
```java
public static class TestClass implements Serializable {
String name;
Set<TestClass> others = new HashSet();
TestClass(String n) { name = n; }
@Override
public int hashCode() {
System.out.println("name=" + name);
return name.hashCode();
}
@Override
public boolean equals(Object other) {
return (other instanceof TestClass) &&
Objects.equals(this.name, ((TestClass) other).name);
}
private static final long serialVersionUID = 20141029195011L;
}
@Test
public void testDeserialization() {
TestClass alice = new TestClass("Alice");
TestClass bob = new TestClass("Bob");
alice.others.add(bob);
bob.others.add(alice);
assertEquals(alice, serializeDeserialize(alice));
}
```
Code for serializeDeserialize is pasted into code box below.
Output
```
name=Bob
name=Alice
name=null
java.lang.NullPointerException
at MyTest$TestClass.hashCode(ComparatorContractTest.java:69)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.readObject(HashSet.java:342)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at java.util.HashSet.readObject(HashSet.java:341)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at org.organicdesign.testUtils.Serialization.serializeDeserialize(Serialization.java:38)
at MyTest.testDeserialization(ComparatorContractTest.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
```
It looks like both objects are deserialized correctly (because they are printed out), but then something tries to deserialize one object a third time and it gets initialized with nulls (or is not initialized).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Cut and paste the test in the description into a Java file and run it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test should pass that the objects match before and after serialization.
ACTUAL -
The objects are not deserialized due to the circular reference and possibly trying to read more objects than were serialized.
---------- BEGIN SOURCE ----------
public static class TestClass implements Serializable {
String name;
Set<TestClass> others = new HashSet<>();
TestClass(String n) { name = n; }
@Override
public int hashCode() {
System.out.println("name=" + name);
return name.hashCode();
}
@Override
public boolean equals(Object other) {
return (other instanceof TestClass) &&
Objects.equals(this.name, ((TestClass) other).name);
}
private static final long serialVersionUID = 20141029195011L;
}
@Test
public void testDeserialization() {
TestClass alice = new TestClass("Alice");
TestClass bob = new TestClass("Bob");
alice.others.add(bob);
bob.others.add(alice);
assertEquals(alice, serializeDeserialize(alice));
}
public static <T> T serializeDeserialize(T obj) {
// This method was started by sblommers. Thanks for your help!
// Mistakes are Glen's.
// https://github.com/GlenKPeterson/Paguro/issues/10#issuecomment-242332099
// Write
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
final byte[] data = baos.toByteArray();
// Read
ByteArrayInputStream baip = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(baip);
return (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I guess you could write your own serialization/deserialization or add a serialization proxy, or your own collection, or your own serialization library. Not really eager to do any of those.
FREQUENCY : always
Same issue with Java 1.8.0_151 and 11.0.1+13. I'm running the test from IntelliJ:
IntelliJ IDEA 2019.1 (Ultimate Edition)
Build #IU-191.6183.87, built on March 27, 2019
JRE: 1.8.0_202-release-1483-b39 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Linux 4.15.0-47-generic
A DESCRIPTION OF THE PROBLEM :
```java
public static class TestClass implements Serializable {
String name;
Set<TestClass> others = new HashSet();
TestClass(String n) { name = n; }
@Override
public int hashCode() {
System.out.println("name=" + name);
return name.hashCode();
}
@Override
public boolean equals(Object other) {
return (other instanceof TestClass) &&
Objects.equals(this.name, ((TestClass) other).name);
}
private static final long serialVersionUID = 20141029195011L;
}
@Test
public void testDeserialization() {
TestClass alice = new TestClass("Alice");
TestClass bob = new TestClass("Bob");
alice.others.add(bob);
bob.others.add(alice);
assertEquals(alice, serializeDeserialize(alice));
}
```
Code for serializeDeserialize is pasted into code box below.
Output
```
name=Bob
name=Alice
name=null
java.lang.NullPointerException
at MyTest$TestClass.hashCode(ComparatorContractTest.java:69)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.readObject(HashSet.java:342)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at java.util.HashSet.readObject(HashSet.java:341)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at org.organicdesign.testUtils.Serialization.serializeDeserialize(Serialization.java:38)
at MyTest.testDeserialization(ComparatorContractTest.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
```
It looks like both objects are deserialized correctly (because they are printed out), but then something tries to deserialize one object a third time and it gets initialized with nulls (or is not initialized).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Cut and paste the test in the description into a Java file and run it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test should pass that the objects match before and after serialization.
ACTUAL -
The objects are not deserialized due to the circular reference and possibly trying to read more objects than were serialized.
---------- BEGIN SOURCE ----------
public static class TestClass implements Serializable {
String name;
Set<TestClass> others = new HashSet<>();
TestClass(String n) { name = n; }
@Override
public int hashCode() {
System.out.println("name=" + name);
return name.hashCode();
}
@Override
public boolean equals(Object other) {
return (other instanceof TestClass) &&
Objects.equals(this.name, ((TestClass) other).name);
}
private static final long serialVersionUID = 20141029195011L;
}
@Test
public void testDeserialization() {
TestClass alice = new TestClass("Alice");
TestClass bob = new TestClass("Bob");
alice.others.add(bob);
bob.others.add(alice);
assertEquals(alice, serializeDeserialize(alice));
}
public static <T> T serializeDeserialize(T obj) {
// This method was started by sblommers. Thanks for your help!
// Mistakes are Glen's.
// https://github.com/GlenKPeterson/Paguro/issues/10#issuecomment-242332099
// Write
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
final byte[] data = baos.toByteArray();
// Read
ByteArrayInputStream baip = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(baip);
return (T) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I guess you could write your own serialization/deserialization or add a serialization proxy, or your own collection, or your own serialization library. Not really eager to do any of those.
FREQUENCY : always
- duplicates
-
JDK-6208166 Deserialization fails with cyclic object graph using HashSet
-
- Open
-