Properties.loadFromXML/storeToXML works incorrectly for supplementary characters after JDK-8042889 was integrated in JDK 9.
Execute the below program to store Properties with supplementary characters :
------------------------------------------------------------------------------------------------------------------------
import java.util.Properties;
public class PropertiesStoreSupplementaryCharacters {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.put("Emoticons", "\uD83D\uDE03");
properties.put("Musical Symbols", "\uD834\uDD1E");
properties.put("CJK Unified Ideographs Extension B", "\uD840\uDC0B");
properties.storeToXML(System.out, null);
}
}
------------------------------------------------------------------------------------------------------------------------
Output on JDK 8 is :
------------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="Emoticons">😃</entry>
<entry key="Musical Symbols">𝄞</entry>
<entry key="CJK Unified Ideographs Extension B">𠀋</entry>
</properties>
------------------------------------------------------------------------------------------------------------------------
Output on JDK 17 is :
------------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="Emoticons">��</entry>
<entry key="Musical Symbols">��</entry>
<entry key="CJK Unified Ideographs Extension B">��</entry>
</properties>
------------------------------------------------------------------------------------------------------------------------
The numeric character references in JDK 17 is incorrect.
Execute the below program to load Properties with supplementary characters :
------------------------------------------------------------------------------------------------------------------------
import java.io.ByteArrayInputStream;
import java.util.Properties;
public class PropertiesLoadSupplementaryCharacters {
public static void main(String[] args) throws Exception {
Properties expected = new Properties();
expected.put("\uD834\uDD1E", "\uD834\uDD1E");
String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">" +
"<properties>" +
"<entry key=\"𝄞\">𝄞</entry>" +
"</properties>";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes("UTF-8"));
Properties props = new Properties();
props.loadFromXML(in);
if (props.equals(expected)) {
System.out.println("Loaded and Expected properties are same");
} else {
System.out.println("Loaded and Expected properties are diferent");
System.out.println("loaded: " + props + ", expected: " + expected);
}
}
}
------------------------------------------------------------------------------------------------------------------------
On JDK 8 it properly parses the character references. Loaded and Expected properties are same.
On JDK 17 it fails to parse the character references and throws InvalidPropertiesFormatException with below stack trace:
------------------------------------------------------------------------------------------------------------------------
Exception in thread "main" java.util.InvalidPropertiesFormatException: jdk.internal.org.xml.sax.SAXParseException;
at java.base/jdk.internal.util.xml.PropertiesDefaultHandler.load(PropertiesDefaultHandler.java:85)
at java.base/java.util.Properties.loadFromXML(Properties.java:960)
at com.openjdk.PropertiesLoadSupplementaryCharacters.main(PropertiesLoadSupplementaryCharacters.java:20)
Caused by: jdk.internal.org.xml.sax.SAXParseException;
at java.base/jdk.internal.util.xml.impl.ParserSAX.panic(ParserSAX.java:652)
at java.base/jdk.internal.util.xml.impl.Parser.ent(Parser.java:1997)
at java.base/jdk.internal.util.xml.impl.Parser.bqstr(Parser.java:2594)
at java.base/jdk.internal.util.xml.impl.Parser.attr(Parser.java:1378)
at java.base/jdk.internal.util.xml.impl.Parser.step(Parser.java:407)
at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:477)
at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:411)
at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:374)
at java.base/jdk.internal.util.xml.impl.SAXParserImpl.parse(SAXParserImpl.java:97)
at java.base/jdk.internal.util.xml.PropertiesDefaultHandler.load(PropertiesDefaultHandler.java:83)
... 2 more
------------------------------------------------------------------------------------------------------------------------