Error unmarshalling xml in java-8 "secure-processing org.xml.sax.SAXNotRecognizedException causing java.lang.IllegalStateException"

The following code worked fine in Java 7

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

String xmlString = '<xml ..... ';

StringReader reader = new StringReader(xmlString);

JAXBContext jc = JAXBContext.newInstance(MyClass.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
MyClass myClass = (MyClass) unmarshaller.unmarshal(reader);
....

Now we had to upgrade to Java 8 and now I get this exception when executing the code:

Sep 03, 2014 1:42:47 PM com.sun.xml.internal.bind.v2.util.XmlFactory createParserFactory
SCHWERWIEGEND: null
org.xml.sax.SAXNotRecognizedException: Feature: http://javax.xml.XMLConstants/feature/secure-processing
    at org.apache.xerces.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:100)
    at com.sun.xml.internal.bind.v2.util.XmlFactory.createParserFactory(XmlFactory.java:114)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.getXMLReader(UnmarshallerImpl.java:139)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)

I know that there is a question targeting a similar problem, but stepping back to java 7 is not a solution for me.

I tried to add the following maven dependency

<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.4</version>
</dependency>

but that did not change the result, so I removed it (thanks to @BlaiseDoughan for the information, that this is included in Java 6)

Any hints are welcome, many thanks.


Solution 1:

We had a similar issue - our head developer found a solution that works for us.

We added this dependency to a couple of our pom.xml files

For those that care, the unit tests in Sonar that were failing were apparently failing because Cobatura by default pulls in an old version of xerces. The version it pulls in is incompatible with JAX-B in Java 8. The library is not used in production code – just Cobatura. Therefore, the fix was to add a test dependency on a more recent version of xerces (2.11.0). This is done by adding the dependency to the pom file:

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>

Solution 2:

Xerces impl is the main culprit here. Remove it. Jdk has inbuilt jaxb parser, you don't need this.

so, if that dependency is coming from a parent project in case of maven use a exclusion tab in case you can't directly remove it.

<exclusion>
                 <groupId>xerces</groupId>  
            <artifactId>xercesImpl</artifactId> 
                </exclusion>

The reason this problem is so hard to detect is because, when you usually write a jaxb unmarshalling code

you will do a unmarshalling on a try block and then catch jaxb exception and then do whatever with the error.

But this culprit parser of a jar (xercesimpl) throws a runtime exception in the middle causing error to not get logged and will be only be detected after careful debugging. Look at the code snippet below

try {
JAXBContext context = JAXBContext.newInstance(YourClass.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            YourClass object = (YourClass)unmarshaller.unmarshal(new StringReader("SomeXmlInString"));


}

catch (JAXBException e){
e.printStackTrace();

}

Here xercesImpl causes the unmarshaller to use some other sax parser (instead of the regular jaxb parser) causing it to throw different exception which won't be caught in our catch block which is expecting a jaxbexception or one of its subclasses.