OpenNLP: documentBuilderFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true) ParserConfigurationException

Viewed 1620

So i'm trying to use OpenNLP within Android Studio, but my application always throws a ParserConfigurationException within this body of code that is used by OpenNLP in their XmlUtil class, which that I am unable to modify:

public static DocumentBuilder createDocumentBuilder() {
    try {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
        return documentBuilderFactory.newDocumentBuilder();
    } catch (ParserConfigurationException var1) {
        throw new IllegalStateException(var1);
    }
}

documentBuilderFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true); causes the application to throw a ParserConfigurationException.

Been stuck on this for about a week now and no luck, any tips for how I can get around this error?

3 Answers

So it turns out that using the given URL "http://javax.xml.XMLConstants/feature/secure-processing" corresponds to XMLConstants.FEATURE_SECURE_PROCESSING -> When the XMLUtils class uses this to set the feature of the documentBuilderFactory -> it will always throw an Exception because this XMLConstant is not recognized for some reason.

In order to remedy this problem and because XMLUtil.java class was unmodifiable as it was being used / grabbed within the opennlp-tools-1.8.3.jar file:

I needed to extract the opennlp-tools-1.8.3.jar down to its .class files and then use ClassEditor (a program for editing .class files) in order to change which feature was being set:

I changed the value of the feature within the XMLUtil.java file to another that would not cause this function to throw an exception:

public static DocumentBuilder createDocumentBuilder() {
    try {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
        return documentBuilderFactory.newDocumentBuilder();
    } catch (ParserConfigurationException var1) {
        throw new IllegalStateException(var1);
    }
}

This allowed me to work around the previously unmodifiable XMLUtil.java file and now documentBuilderFactory.setFeature will not throw an Exception, allowing me to use the slightly modified code within the OpenNLP library!

I had the same problem using version 1.9.1 of OpenNLP and I solved this by using version 1.6.0 instead. This is the latest version I've managed to get working.

dependencies {
  implementation 'org.apache.opennlp:opennlp-tools:1.6.0'
}

Downgrading was seamless since the models are the same and the public API is largely similar (at least for my use).


Full story: I was making a prototype with OpenNLP to use a TokenizerME and two NameFinderME -- for persons and locations. These are all the versions of OpenNLP I've tried (and failed with):

  • 1.9.1 and 1.9.0: failing with the ParserConfigurationException described in the OP
  • 1.8.0 and 1.7.0: both crash with an OutOfMemoryError when trying to load the NameFinderME

@Keaton MacLeod 's answer worked for me too, but instead of modifying the class file, I edited the XmlUtil.java file after cloning their source repo and rebuilding the required jar file. Comment or remove this line and this one. Build the opennlp project by following their build instructions Add the resulting jar to your project and it should work as expected

Related