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

ObjectStreamClass.getName() does not comply with the spec for arrays

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 6
    • 5.0
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.5.0_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
      Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)

      java version "1.4.2_06"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
      Java HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed mode)

      java version "1.3.1_15"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_15-b01)
      Java HotSpot(TM) Client VM (build 1.3.1_15-b01, mixed mode)

      And oldier versions too !


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      The java.io.ObjectStreamClass.getName() does not comply with its specifications. Actually, the Java Object Serialization specification (revision 1.5.0 and previous ones too) at chapter 4.1, page 44, says that the getName() method returns the fully-qualified name of the class. However, when the underlying class is an array type, the String returned is not its fully-qualified name but the VM internal representation.

      For instance, when I deserialize my array of objects whose type is "persistence.MyClass", the related ObjectStreamClass returns "[Lpersistence.MyClass;" when calling its getName() method.

      The Java Language Specification clearly says at section "6.7 Fully Qualified Names and Canonical Names" that:
      -The fully qualified name of an array type consists of the fully qualified name of the component type of the array type followed by "[]".


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the following code. You will see on the standard ouput that when dealing with an array type the ObjectStreamClass.getName() returns the VM internal representation of the class not its fully-qualified name.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expected the ObjectStreamClass.getName() to return "persistence.MyClass[]" not "[Lpersistence.MyClass;" when the instance of ObjectStreamClass is related to an array of "persistence.MyClass".

      ACTUAL -
      I get the VM internal representation of the array type not its fully qualified name.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package persistence;

      import java.io.*;

      public class Test5
      {
          public static void main(String[] args) throws Exception
          {
              final MyClass[] myArray = new MyClass[] { new MyClass("object1"), new MyClass("object2") };

              File file = new File("test.srl");
              FileOutputStream fos = null;
              try
              {
                  fos = new FileOutputStream(file);
                  ObjectOutputStream oos = new ObjectOutputStream(fos);
                  oos.writeObject(myArray);
                  oos.flush();
              }
              finally
              {
                  if (fos != null)
                  {
                      try
                      {
                          fos.close();
                      }
                      catch (Exception ignore) {}
                  }
              }

              Object object = null;
              FileInputStream fis = null;
              try
              {
                  fis = new FileInputStream(file);
                  MyObjectInputStream ois = new MyObjectInputStream(fis);
                  object = ois.readObject();
              }
              finally
              {
                  if (fis != null)
                  {
                      try
                      {
                          fis.close();
                      }
                      catch (Exception ignore) {}
                  }
              }

              if (object == null)
              {
                  System.out.println("Object has not been restored");
              }
              else
              {
                  System.out.println("Object has been restored");
                  MyClass[] restoredArray = (MyClass[]) object;
                  System.out.println("Restored array length=" + restoredArray.length);
              }
          }

          private static class MyObjectInputStream extends ObjectInputStream
          {
              protected MyObjectInputStream(InputStream in) throws IOException, StreamCorruptedException
              {
                  super(in);
              }

              protected Class resolveClass(ObjectStreamClass classDesc) throws ClassNotFoundException, IOException
              {
                  String className = classDesc.getName();
                  System.out.println("Resolving class: " + className);

                  return super.resolveClass(classDesc);
              }
          }
      }

      class MyClass implements Serializable
      {
          private String name;

          public MyClass(String name)
          {
              this.name = name;
          }

          public String toString()
          {
              return name;
          }
      }

      ---------- END SOURCE ----------
      ###@###.### 2005-2-14 13:05:17 GMT

            aozerov Andrey Ozerov
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: