JDK-8016344 : (props) Properties.storeToXML behaviour has changed from JDK 6 to 7
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 7u17,8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-05-21
  • Updated: 2014-11-17
  • Resolved: 2013-10-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 8
8 b115Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
1.7.0_17

ADDITIONAL OS VERSION INFORMATION :
Version 6.0.6000


EXTRA RELEVANT SYSTEM CONFIGURATION :
Not system related

A DESCRIPTION OF THE PROBLEM :
If you construct a Properties object with a default Properties object in the constructor, add some more properties, and then dump the results with storeToXML you get different results when running Java 6 and Java 7.

Java 6 only exports the new properties and not the defaults.
Java 7 (1.7.0_17)  includes the defaults.

The Store method does not export the defaults.


REGRESSION.  Last worked in version 6u45

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a Properties object A.
Add properties.
Construct a new Properties object B using A as the default.
Add more properties.
Export using storeToXML.

Compare J7 output with J6.




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Result from Java6
<?xml version= " 1.0 "  encoding= " UTF-8 "  standalone= " no " ?>
<!DOCTYPE properties SYSTEM  " http://java.sun.com/dtd/properties.dtd " >
<properties>
<comment>Try export with 1.6.0_35</comment>
<entry key= " common " >This property is from B</entry>
<entry key= " name_propB " >This property is from B</entry>
</properties>


ACTUAL -
Result from Java 7
<?xml version= " 1.0 "  encoding= " UTF-8 "  standalone= " no " ?>
<!DOCTYPE properties SYSTEM  " http://java.sun.com/dtd/properties.dtd " >
<properties>
<comment>Try export with 1.7.0_17</comment>
<entry key= " common " >This property is from B</entry>
<entry key= " name_propB " >This property is from B</entry>
<entry key= " name_propA " >This property is from A</entry>
</properties>



REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Properties;
import java.io.FileOutputStream;
import java.io.File;

class TestProperties {
       public static void main(String[] args) {
               String outputName = args.length > 0 ? args[0] :  " dump.txt " ;
               System.out.println( " Java version  "  + System.getProperty( " java.version " ));
               
               Properties propsA = new Properties();
               propsA.setProperty( " name_propA " ,  " This property is from A " );
               propsA.setProperty( " common " ,  " This property is from A " );
               
               Properties propsB = new Properties(propsA);
               propsB.setProperty( " name_propB " ,  " This property is from B " );
               propsB.setProperty( " common " ,  " This property is from B " );
               
               try {
                       FileOutputStream fo = new FileOutputStream(new File(outputName));
                       propsB.storeToXML(fo,  " Try export with  "  + System.getProperty( " java.version " ));
               } catch (Exception ex) {
                       System.out.println( " Exception  "  + ex);
               }
       }
} 
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
This can be worked around if the difference in behavour is known. However, there is nothing I can see in the Javadocs that would have made the behaviour change apparent. The documentation for 6 and 7 appears ambiguous as to which behaviour is correct.

Difficult to see how the behaviour can be 'corrected' now as any change will have a impact on already distributed code. However, the Javadocs could flag the difference.
Comments
The fix will need to be different for 7u and 8 as the code in 8 is completely new - but in all likelihood 'imported' its spec from the 7 code...
16-10-2013

It looks as this is a regression introduced by JDK-6977738. More precisely: --- a/src/share/classes/java/util/XMLUtils.java Mon Oct 11 10:55:04 2010 +0100 +++ b/src/share/classes/java/util/XMLUtils.java Mon Oct 11 20:22:27 2010 -0700 @@ -141,14 +141,13 @@ class XMLUtils { comments.appendChild(doc.createTextNode(comment)); } - Set keys = props.keySet(); - Iterator i = keys.iterator(); - while(i.hasNext()) { - String key = (String)i.next(); - Element entry = (Element)properties.appendChild( - doc.createElement("entry")); - entry.setAttribute("key", key); - entry.appendChild(doc.createTextNode(props.getProperty(key))); + synchronized (props) { + for (String key : props.stringPropertyNames()) { + Element entry = (Element)properties.appendChild( + doc.createElement("entry")); + entry.setAttribute("key", key); + entry.appendChild(doc.createTextNode(props.getProperty(key))); + } } emitDocument(doc, os, encoding); } Whereas props.keySet() returned only local names, props.stringPropertyNames() will prepend the parent Properties' names.
16-10-2013