-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
1.4.2
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.4.2_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_12-b03)
Java HotSpot(TM) Client VM (build 1.4.2_12-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Properties that are set using lazy initialization pattern don't get encoded by XmlEncoder unlike binary serialization.
The example source code below shows two bean properties being set lazily with two different techniques, one using a constant and another calling a factory method.
The lazy initialization code is invoked in the getter methods. This is performed by invoking toString method of the Bean without calling any setter methods.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.2_12" class="java.beans.XMLDecoder">
<object class="com.uhc.ubh.service.bean.Bean">
<void property="flavor">
<string>MEDIUM ROAST</string>
</void>
<void property="type">
<string>COLUMBIAN</string>
</void>
</object>
</java>
ACTUAL -
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.2_12" class="java.beans.XMLDecoder">
<object class="com.uhc.ubh.service.bean.Bean"/>
</java>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
public class Bean implements Serializable {
private static final String DEFAULT_FLAVOR = "MEDIUM ROAST";
private String type = null;
private String flavor = null;
public String getType() {
if (type == null) type = new BeanFactory().getType();
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFlavor() {
if (flavor == null) flavor = DEFAULT_FLAVOR;
return flavor;
}
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public String toString() {
return getType() + " " + getFlavor();
}
public static class BeanFactory {
public String getType() {
return "COLUMBIAN";
}
public String getFlavor() {
return "MEDIUM ROAST";
}
}
public static void main(String[] args) {
Bean bean = new Bean();
//This following line should initialize the bean properties
System.out.println(bean.getType() + bean.getFlavor());
System.out.println(encodeAsXml(bean));
}
private static String encodeAsXml(Object bean) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLEncoder encoder = null;
try {
encoder = new XMLEncoder(
new BufferedOutputStream(out));
encoder.writeObject(bean);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (encoder != null) encoder.close();
}
return out.toString();
}
}
---------- END SOURCE ----------
java version "1.4.2_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_12-b03)
Java HotSpot(TM) Client VM (build 1.4.2_12-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Properties that are set using lazy initialization pattern don't get encoded by XmlEncoder unlike binary serialization.
The example source code below shows two bean properties being set lazily with two different techniques, one using a constant and another calling a factory method.
The lazy initialization code is invoked in the getter methods. This is performed by invoking toString method of the Bean without calling any setter methods.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.2_12" class="java.beans.XMLDecoder">
<object class="com.uhc.ubh.service.bean.Bean">
<void property="flavor">
<string>MEDIUM ROAST</string>
</void>
<void property="type">
<string>COLUMBIAN</string>
</void>
</object>
</java>
ACTUAL -
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.2_12" class="java.beans.XMLDecoder">
<object class="com.uhc.ubh.service.bean.Bean"/>
</java>
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
public class Bean implements Serializable {
private static final String DEFAULT_FLAVOR = "MEDIUM ROAST";
private String type = null;
private String flavor = null;
public String getType() {
if (type == null) type = new BeanFactory().getType();
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFlavor() {
if (flavor == null) flavor = DEFAULT_FLAVOR;
return flavor;
}
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public String toString() {
return getType() + " " + getFlavor();
}
public static class BeanFactory {
public String getType() {
return "COLUMBIAN";
}
public String getFlavor() {
return "MEDIUM ROAST";
}
}
public static void main(String[] args) {
Bean bean = new Bean();
//This following line should initialize the bean properties
System.out.println(bean.getType() + bean.getFlavor());
System.out.println(encodeAsXml(bean));
}
private static String encodeAsXml(Object bean) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLEncoder encoder = null;
try {
encoder = new XMLEncoder(
new BufferedOutputStream(out));
encoder.writeObject(bean);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (encoder != null) encoder.close();
}
return out.toString();
}
}
---------- END SOURCE ----------
- relates to
-
JDK-6490736 LTP: XmlEncoder causes side-effect when using lazy initialization getter code
- Closed
-
JDK-6490732 LTP: XmlEncoder disregards properties set with values that match the getter values
- Closed