2

I am trying to set features on a DocumentBuilderFactory. However, it just throws a javax.xml.parsers.ParserConfigurationException with the features name as the message:

public void execute() throws Exception
{
    // Get the factory.
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

    // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
    // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
    setFeature(dbf, "http://xml.org/sax/features/external-general-entities", false);

    // Xerces 2 only - http://xerces.apache.org/xerces-j/features.html#external-general-entities
    setFeature(dbf, "http://apache.org/xml/features/disallow-doctype-decl", true);

    ...
}

private void setFeature(DocumentBuilderFactory dbf, String name, boolean value)
{
    try {
        dbf.setFeature(name, value);
    } catch (ParserConfigurationException e) {
        e.printStackTrace(); // <- see below
    }
}

The error gives no useful information:

javax.xml.parsers.ParserConfigurationException: http://xml.org/sax/features/external-general-entities
    at org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl.setFeature(DocumentBuilderFactoryImpl.java:101)
    at com.kounta.printing.epson.EpsonReceiptTranslator.setFeature(EpsonReceiptTranslator.java:76)
    at com.kounta.printing.epson.EpsonReceiptTranslator.execute(EpsonReceiptTranslator.java:49)
    at com.kounta.printing.epson.EpsonPrintJob$1.run(EpsonPrintJob.java:48)
    at com.kounta.util.TaskQueue.internalRun(TaskQueue.java:68)
    at com.kounta.util.TaskQueue.access$100(TaskQueue.java:11)
    at com.kounta.util.TaskQueue$InternalRunnable.run(TaskQueue.java:79)
    at java.lang.Thread.run(Thread.java:841)

Is there a way to get all the supported features? Or am I doing something wrong? Both features throw an exception.

Elliot Chance
  • 5,526
  • 10
  • 49
  • 80
  • I believe the underlying parser is Xerxes, in which case the list of features is available [here](https://xerces.apache.org/xerces2-j/features.html) – Jim Garrison Oct 23 '15 at 02:00
  • @JimGarrison, that's the page I was using but even though the feature is listed it throws an exception. Thats why I want to see a list of features at runtime. – Elliot Chance Oct 23 '15 at 03:16
  • 1
    Then maybe it's not Xerces? Use an IDE, set a breakpoint on the first `setFeature` and try to determine the runtime class of the parser by examining the `DocumentBuilderFactory`. – Jim Garrison Oct 23 '15 at 05:18

1 Answers1

1

So it turns out that the XML parser that is shipped by default is rubbish and incomplete (not surprising since this is android) and I found the issue eventually:

https://android.googlesource.com/platform/libcore/+/6bcf32ab404c39b85d25430f6df16503ef3526cf/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java#101

So despite the documentation requiring that all XML parsers support FEATURE_SECURE_PROCESSING -http://developer.android.com/reference/javax/xml/parsers/SAXParserFactory.html#setFeature(java.lang.String,%20boolean) - this does not.

The solution is I will have to use a different library to handle the parsing of the XML.

Elliot Chance
  • 5,526
  • 10
  • 49
  • 80
  • 1
    In their defence, it's worth pointing out that a lot of XML parsers were written to this interface long before this requirement was added to the documentation. JAXP has a bad track record at introducing incompatibilities by changing the documentation, without actually changing the technical interface. – Michael Kay Oct 23 '15 at 08:30