JDK-8016545 : java.beans.XMLEncoder.writeObject output is wrong
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 7,7u15
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-04-16
  • Updated: 2014-11-17
  • Resolved: 2013-06-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u67Fixed 8 b98Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_15 " 
Java(TM) SE Runtime Environment (build 1.7.0_15-b03)
Java HotSpot(TM) Client VM (build 23.7-b01, mixed mode, sharing)

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

A DESCRIPTION OF THE PROBLEM :
If Bean properties are initialized with static values, XMLEncoder.writeObject sometimes writes out nonsense. So XMLDecoder.readObject can't read the Java bean correctly. See example!


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Type in the given example (Class Test) and run it. It writes out a wrong serialization of Test$MyClass.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expected result from the Test example is:

<?xml version= " 1.0 "  encoding= " UTF-8 " ?>
<java version= " 1.7.0_15 "  class= " java.beans.XMLDecoder " >
 <object class= " Test$MyClass " >
  <void id= " Boolean0 "  property= " gut " />
  <void property= " info " >
   <object class= " Test$Info " >
    <void property= " enabled " >
     <object idref= " Boolean0 " />
    </void>
    <void property= " IEin " >
     <int>1</int>
    </void>
   </void>
  </void>
  <void property= " sticky " >
   <boolean>false</boolean>
  </void>
 </object>
</java>

OK

You can produce this output by changing in the example the line
private Info info = new Info();
to
private Info info;



ACTUAL -
The example produces the following wrong output:

<?xml version= " 1.0 "  encoding= " UTF-8 " ?>
<java version= " 1.7.0_15 "  class= " java.beans.XMLDecoder " >
 <object class= " Test$MyClass " >
  <void property= " info " >
   <void property= " IEin " >
    <int>1</int>
   </void>
   <void property= " enabled " >
    <void class= " Test$MyClass "  id= " Test$MyClass0 " >
     <void id= " Boolean0 "  property= " gut " />
     <void property= " sticky " >
      <boolean>false</boolean>
     </void>
    </void>
    <object idref= " Boolean0 " />
   </void>
  </void>
 </object>
</java>

Expected sticky=false, but is=null

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;

public class Test {
    
    public static void main(String[] args) throws Exception {

        MyClass m = new MyClass();
        m.setSticky(Boolean.FALSE);
        Info omi = new Info();
        omi.setEnabled(Boolean.TRUE);
        omi.setIEin(new Integer(1));
        m.setInfo(omi);

        ByteArrayOutputStream arraystream = new ByteArrayOutputStream();
        XMLEncoder encoder = new XMLEncoder(arraystream);
        encoder.writeObject(m);
        encoder.close();
        arraystream.close();
        System.out.println(arraystream.toString());

        XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(arraystream.toByteArray()));
        m = (MyClass) decoder.readObject();
        decoder.close();
        if (!Boolean.FALSE.equals(m.getSticky())) {
            System.out.println( " Expected sticky=false, but is= "  + m.getSticky());
        } else {
            System.out.println( " OK " );
        }
    }

    public static class MyClass {
        
        private Info info = new Info();
        public Info getInfo() {
            return this.info;
        }
        public void setInfo(Info anInfo) {
            this.info = anInfo;
        }
        
        private Boolean gut = Boolean.TRUE;
        public java.lang.Boolean getGut() {
            return this.gut;
        }
        public void setGut(Boolean gut) {
            this.gut = gut;
        }

        private Boolean sticky;
        public Boolean getSticky() {
            return this.sticky;
        }
        public void setSticky(Boolean sticky) {
            this.sticky = sticky;
        }
    }
    
    public static class Info {

        private Integer iEin;
        public Integer getIEin() {
            return this.iEin;
        }
        public void setIEin(Integer iEin) {
            this.iEin = iEin;
        }

        private Boolean enabled;
        public Boolean getEnabled() {
            return this.enabled;
        }
        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Avoid setting bean properties to static values, especially when the bean is instantiated (constructor or variable declaration).