JDK-8040275 : XMLDecoder fails to read XML files with idref attributes
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 7u45
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • Submitted: 2013-11-11
  • Updated: 2014-04-15
  • Resolved: 2014-04-15
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
Linux mcz800l 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When using XMLEncoder.wroteObject to write an XML representation of a map containing a list of arrays, if any of the arrays are duplicated in the list, the generated XML will contain elements with "idref" attributes.

When reading this XML with XMLDecoder.readObject, the following message will appear:

java.lang.NoSuchMethodException: <unbound>=ArrayList.add();
Continuing ...

and the duplicated array will not be restored.

XMLDecoder.readObject works correctly with this workflow using Java 1.6, but fails in 1.7 (I'm using update 45).

REGRESSION.  Last worked in version 6u43

ADDITIONAL REGRESSION INFORMATION:
java version "1.6.0_27"
Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
Java HotSpot(TM) 64-Bit Server VM (build 20.2-b06, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just compile and execute the included program.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
This program should run without any errors.  It runs without errors using Java 1.6 update 27.  The output should look like:

Number of arrays in original list: 4
Number of arrays in restored list: 4

ACTUAL -
When running with Java 1.7 update 45, received this output:

          Number of arrays in original list: 4
          java.lang.NoSuchMethodException: <unbound>=ArrayList.add();
          Continuing ...
          Number of arrays in restored list: 3

One of the duplicated arrays in the list is not restored.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NoSuchMethodException: <unbound>=ArrayList.add();
Continuing ...


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XMLDecoderProblem {


    public static void main(String[] args) throws IOException {
        String key = "DecodeTest";

        int[] array1 = {1, 2, 3, 4};
        int[] array2 = {1, 2, 3, 4};
        int[] array3 = {99};

        Map<String, Object> map = new HashMap<String, Object>();
        List<Object> list = new ArrayList<Object>();

        list.add(array1);
        list.add(array2);
        list.add(array3);
        list.add(array3);

        map.put(key, list);
        System.out.println("Number of arrays in original list: " + list.size());

        String savedStateMap = serializeMapToString(map);

        Map<String, Object> restoredMap = readMapFromString(savedStateMap);
        List<Object> restoredList = (List<Object>) restoredMap.get(key);
        System.out.println("Number of arrays in restored list: " + restoredList.size());

    }


    public static String serializeMapToString(Map<String, Object> stateMap) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XMLEncoder encoder = new XMLEncoder(baos);
        encoder.writeObject(stateMap);
        encoder.close();
        String s = baos.toString("UTF-8");
        return s;
    }

    public static Map<String, Object> readMapFromString(String savedStateMap) throws IOException {
        ByteArrayInputStream bais = new ByteArrayInputStream(savedStateMap.getBytes("UTF-8"));
        XMLDecoder decoder = new XMLDecoder(bais);
        Map<String, Object> stateMap = (Map<String, Object>) decoder.readObject();
        decoder.close();
        return stateMap;
    }

}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
We have created an XSLT to transform the XML file to no longer contain the idrefs.  This is the transform we are using:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- 'idkey' is declared as a key's name for any element, which has the
'id' attribute. The 'id' value is the key's value. -->
<xsl:key name="idkey" match="*[@id]" use="@id" />

<!-- Default copy template -->
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>

<!-- Remove id attributes -->
<xsl:template match="@id" />

<!-- Dereference -->
<xsl:template match="node()[@idref]">
<xsl:apply-templates select="key('idkey', @idref)" />
</xsl:template>

</xsl:stylesheet>
Comments
Seems this issue is related to the 8027066, because it is not reproducible with 7u60 b14.
15-04-2014

It is not reproducible with 9 and 8b129, but it is reproducible with 8b99 and 7u45b04.
15-04-2014