A DESCRIPTION OF THE PROBLEM :
Preferences.exportSubtree() allows users to export XML that cannot later be imported via Preferences.importPreferences() because the former correctly (?) XML encodes control characters (e.g. \u0018 becomes ) just fine, but the parse will complain about invalid XML characters on import.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See test case.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Preferences export followed by import should work, or at least fail fast on export, or do some Preferences API specific custom encoding/decoding.
ACTUAL -
Exception in thread "main" java.util.prefs.InvalidPreferencesFormatException: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 39; Character reference "" is an invalid XML character.
at java.prefs/java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:216)
at java.prefs/java.util.prefs.Preferences.importPreferences(Preferences.java:1289)
at test.Main.main(Main.java:21)
Caused by: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 39; Character reference "" is an invalid XML character.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1471)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.scanCharReferenceValue(XMLScanner.java:1344)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(XMLScanner.java:895)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(XMLDocumentFragmentScannerImpl.java:1512)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1353)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2710)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:246)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at java.prefs/java.util.prefs.XmlSupport.loadPrefsDoc(XmlSupport.java:250)
at java.prefs/java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:199)
... 2 more
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.util.prefs.Preferences;
public class Main {
public static void main(String[] args) throws Exception {
Preferences p = Preferences.userRoot().node("test");
p.put("key", "[\u0018\u0019]");
File f = new File("preferences.xml");
p.exportSubtree(new FileOutputStream(f));
System.out.println(Files.readString(f.toPath()));
Preferences.importPreferences(new FileInputStream(f));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Ask users not to paste control characters into text fields that happens to be persisted via the Preferences API.
FREQUENCY : always
Preferences.exportSubtree() allows users to export XML that cannot later be imported via Preferences.importPreferences() because the former correctly (?) XML encodes control characters (e.g. \u0018 becomes ) just fine, but the parse will complain about invalid XML characters on import.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See test case.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Preferences export followed by import should work, or at least fail fast on export, or do some Preferences API specific custom encoding/decoding.
ACTUAL -
Exception in thread "main" java.util.prefs.InvalidPreferencesFormatException: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 39; Character reference "" is an invalid XML character.
at java.prefs/java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:216)
at java.prefs/java.util.prefs.Preferences.importPreferences(Preferences.java:1289)
at test.Main.main(Main.java:21)
Caused by: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 39; Character reference "" is an invalid XML character.
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1471)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.scanCharReferenceValue(XMLScanner.java:1344)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(XMLScanner.java:895)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(XMLDocumentFragmentScannerImpl.java:1512)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1353)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2710)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:246)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at java.prefs/java.util.prefs.XmlSupport.loadPrefsDoc(XmlSupport.java:250)
at java.prefs/java.util.prefs.XmlSupport.importPreferences(XmlSupport.java:199)
... 2 more
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.util.prefs.Preferences;
public class Main {
public static void main(String[] args) throws Exception {
Preferences p = Preferences.userRoot().node("test");
p.put("key", "[\u0018\u0019]");
File f = new File("preferences.xml");
p.exportSubtree(new FileOutputStream(f));
System.out.println(Files.readString(f.toPath()));
Preferences.importPreferences(new FileInputStream(f));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Ask users not to paste control characters into text fields that happens to be persisted via the Preferences API.
FREQUENCY : always