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

XMLDecoder in java 7 cannot properly deserialize object arrays

    XMLWordPrintable

Details

    • Bug
    • Status: Resolved
    • P4
    • Resolution: Fixed
    • 8
    • 8
    • client-libs
    • b115
    • generic
    • generic

    Backports

      Description

        XMLDecoder in Java 7 cannot properly deserialize object arrays.
        In the following test case, the faulty object has an object array referenced
        by two of its fields (in the example: messages and detailedMessages). As soon
        as a reference is
        declared over an array, the problem arises.

        Note also that the serialized XML seems valid, and only the deserialization
        behaves incorrectly.

        Test case:

        import java.beans.XMLDecoder;
        import java.beans.XMLEncoder;
        import java.io.ByteArrayInputStream;
        import java.io.ByteArrayOutputStream;
        import java.util.Arrays;

        public class XMLEncoderTests {
          public static class Wrapper {
             private String[] messages;
             private String[] detailedMessages;

             public String[] getDetailedMessages() {
                return detailedMessages;
             }

             public void setDetailedMessages(String[] messages) {
                this.detailedMessages = messages;
             }

             public String[] getMessages() {
                return messages;
             }

             public void setMessages(String[] messages) {
                this.messages = messages;
             }

             @Override
             public String toString() {
                return "Wrapper - Messages {" + Arrays.deepToString(getMessages())
        + "}, Detailed Messages {"
                      + Arrays.deepToString(getDetailedMessages()) + "}";
             }

             @Override
             public boolean equals(Object other) {
                if (other instanceof Wrapper) {
                   Wrapper otherWrapper = (Wrapper) other;
                   // Compare messages and otherWrapper messages.
                   String[] otherMessages = otherWrapper.getMessages();
                   String[] messages = this.getMessages();

                   if (!Arrays.equals(messages, otherMessages)) {
                      return false;
                   }

                   // And compare detailedMessage and otherWrapperdetailedMessages.
                   otherMessages = otherWrapper.getDetailedMessages();
                   messages = this.getDetailedMessages();

                   if (!Arrays.equals(messages, otherMessages)) {
                      return false;
                   }

                   return true;
                } else {
                   return false;
                }
             }
          }

          public static void main(String[] args) {
             ByteArrayOutputStream stream = new ByteArrayOutputStream();
             XMLEncoder encoder = new XMLEncoder(stream);
             Wrapper wrapper = new Wrapper();
             String[] messages = new String[] { "First message", "Second message"
        };

             wrapper.setMessages(messages);
             wrapper.setDetailedMessages(messages);

             encoder.writeObject(wrapper);
             encoder.close();

             String output = stream.toString();
             System.out.println(output);

             // now decode it.
             XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream
        (output.getBytes()));
             Object obj = decoder.readObject();
             decoder.close();

             // Validate object are equals.
             if (!wrapper.equals(obj)) {
                System.out.println("FAILURE: Objects are not equals!");
             } else {
                System.out.println("Objects are equals.");
             }
             System.out.println("Original wrapper: " + wrapper);
             System.out.println("Deserialized wrapper: " + obj);
          }
        }

        When running the above code with JDK 6, the objects are equals (i.e.
        The original object and the serialized/deserialized version are the same)
        and there is no bug. When running the above code with JDK 7, the objects are
        not equals since the deserialized detailedMessages field is null.

        Output running the above test case with JDK 7:
        <?xml version="1.0" encoding="UTF-8"?>
        <java version="1.7.0_45" class="java.beans.XMLDecoder">
         <object class="XMLEncoderTests$Wrapper">
          <void property="detailedMessages">
           <array class="java.lang.String" length="2" id="StringArray0">
            <void index="0">
             <string>First message</string>
            </void>
            <void index="1">
             <string>Second message</string>
            </void>
           </array>
          </void>
          <void property="messages">
           <object idref="StringArray0"/>
          </void>
         </object>
        </java>

        FAILURE: Objects are not equals!
        Original wrapper: Wrapper - Messages {[First message, Second message]},
        Detailed Messages {[First message, Second message]}
        Deserialized wrapper: Wrapper - Messages {[First message, Second message]},
        Detailed Messages {null}

        Attachments

          Issue Links

            Activity

              People

                anashaty Anton Nashatyrev (Inactive)
                anashaty Anton Nashatyrev (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: