-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
17, 25
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
Ubuntu 24.04
A DESCRIPTION OF THE PROBLEM :
Non initialized field during deserialization if record is referenced in cycle.
There is small reproduction sample:
record Person(SomeClass name) implements Serializable {}
class SomeClass implements Serializable {
Person p1;
@Override
public String toString() {
return "SomeClass{" +
"p1 is Null: " + (p1 == null) +
'}';
}
}
public class DeserializationBug {
public static void main(String[] args) {
String filename = "person.ser";
// Serialization
var originalPerson = new Person(new SomeClass());
originalPerson.name().p1 = originalPerson;
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
oos.writeObject(originalPerson);
System.out.println("Object serialized successfully: " + originalPerson);
} catch (IOException e) {
System.err.println("Serialization failed: " + e.getMessage());
}
// Deserialization
Person deserializedPerson = null;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
deserializedPerson = (Person) ois.readObject();
System.out.println("Object deserialized successfully: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
System.err.println("Deserialization failed: " + e.getMessage());
}
}
}
Output:
Object serialized successfully: Person[name=SomeClass{p1 is Null: false}]
Object deserialized successfully: Person[name=SomeClass{p1 is Null: true}]
If we switch record class to general one, then deserialization works as expected, e.g.:
```
class Person implements Serializable {
private final SomeClass someClass;
Person(SomeClass name) {
this.someClass = name;
}
public SomeClass name() {
return someClass;
}
@Override
public String toString() {
return "Person{" +
"name=" + someClass +
'}';
}
}
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute code (same as in Testcase Code):
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Object serialized successfully: Person{name=SomeClass{p1 is Null: false}}
Object deserialized successfully: Person{name=SomeClass{p1 is Null: false}}
ACTUAL -
Object serialized successfully: Person[name=SomeClass{p1 is Null: false}]
Object deserialized successfully: Person[name=SomeClass{p1 is Null: true}]
---------- BEGIN SOURCE ----------
Attached above
---------- END SOURCE ----------
Ubuntu 24.04
A DESCRIPTION OF THE PROBLEM :
Non initialized field during deserialization if record is referenced in cycle.
There is small reproduction sample:
record Person(SomeClass name) implements Serializable {}
class SomeClass implements Serializable {
Person p1;
@Override
public String toString() {
return "SomeClass{" +
"p1 is Null: " + (p1 == null) +
'}';
}
}
public class DeserializationBug {
public static void main(String[] args) {
String filename = "person.ser";
// Serialization
var originalPerson = new Person(new SomeClass());
originalPerson.name().p1 = originalPerson;
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
oos.writeObject(originalPerson);
System.out.println("Object serialized successfully: " + originalPerson);
} catch (IOException e) {
System.err.println("Serialization failed: " + e.getMessage());
}
// Deserialization
Person deserializedPerson = null;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
deserializedPerson = (Person) ois.readObject();
System.out.println("Object deserialized successfully: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
System.err.println("Deserialization failed: " + e.getMessage());
}
}
}
Output:
Object serialized successfully: Person[name=SomeClass{p1 is Null: false}]
Object deserialized successfully: Person[name=SomeClass{p1 is Null: true}]
If we switch record class to general one, then deserialization works as expected, e.g.:
```
class Person implements Serializable {
private final SomeClass someClass;
Person(SomeClass name) {
this.someClass = name;
}
public SomeClass name() {
return someClass;
}
@Override
public String toString() {
return "Person{" +
"name=" + someClass +
'}';
}
}
```
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute code (same as in Testcase Code):
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Object serialized successfully: Person{name=SomeClass{p1 is Null: false}}
Object deserialized successfully: Person{name=SomeClass{p1 is Null: false}}
ACTUAL -
Object serialized successfully: Person[name=SomeClass{p1 is Null: false}]
Object deserialized successfully: Person[name=SomeClass{p1 is Null: true}]
---------- BEGIN SOURCE ----------
Attached above
---------- END SOURCE ----------