Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8365997

Non initialized field during deserialization if record is referenced in cycle

XMLWordPrintable

      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 ----------

            asajeev Anjana Sajeev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: