32

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.

Community
  • 1
  • 1
mmx73
  • 972
  • 1
  • 8
  • 19

13 Answers13

56

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>
Robert H.
  • 561
  • 4
  • 2
  • 1
    Somehow javax.xml.bind.JAXBContext in C:\Java64\jdk1.8.0_60\jre\lib\rt.jar is not working correctly. The solution is to use an earlier version of xerces in the CLASSPATH. In pom.xml, insert the above-mentioned xerces 2.11.0 dependency on top of all other so it has the higher priority to be picked up by Java 8. – oraclesoon Oct 30 '15 at 09:56
  • With Jdk v1.8.0_181 and Jaxb v2.2.11 and xercesIml v2.11.0 this solution is not working – Csaba Tenkes Jan 24 '19 at 09:24
  • this doesn't work for me. I test version 2.12.0 also, but does not work !. my java version is 1.8.0_202 – M2E67 Sep 14 '19 at 05:18
25

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.

shashwatZing
  • 1,550
  • 1
  • 17
  • 24
22

Another possible solution to this is to add system variables:

I used these in the maven tomcat plugin which worked for me:

<javax.xml.parsers.DocumentBuilderFactory>com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<org.xml.sax.parser>com.sun.org.apache.xerces.internal.parsers.SAXParser</org.xml.sax.parser>
<javax.xml.parsers.SAXParserFactory>com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>

But you should also be able to set as follows:

java -Dorg.xml.sax.parser="com.sun.org.apache.xerces.internal.parsers.SAXParser" \
-Djavax.xml.parsers.DocumentBuilderFactory="com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" \
-Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"

or even use System.setProperty:

System.setProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser");
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
Mitch1077487
  • 799
  • 6
  • 8
  • This worked for me. Can you explain what exactly it does. – Naveen Nov 01 '18 at 15:50
  • great if you can't rebuild the java. In jruby use `java.lang.System.setProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser");` etc. – meesern Jul 15 '19 at 14:24
  • The system prop "jdk.xml.entityExpansionLimit" was being ignored for me until I set those three properties at the bottom. Thanks, you saved my buns... but why do I have to set the parsers properties in order to have other properties like "jdk.xml.entityExpansionLimit" take effect? – Alkanshel Jan 06 '20 at 18:17
9

It was a dependency problem.

Here is my way how I solved the problem:

  1. Make a new maven project, with that simple pieces of code, I attached below, the programm crashed normally with an error, that the structure couldn't be parsed which is ok.
  2. Copy your dependencies into the project pom.xml, now the programm should crash (as described above)

  3. no you remove dependencies after your favoured method (good guessing, Bisection , 1-by-1 ..) to find the "bad" dependency. Maybe someone has a better (more professional) method, this one worked for me.

now you can descide what to do, maybe a new version is available, in our case it was out own package of a colleage, where he included a package of a colleage, which i could exclude.

public class Test {
    public Test() {
    }
    public static void main(String[] args) {
        try {
            StringReader reader = new StringReader("<xml></xml>");
            JAXBContext jc = JAXBContext.newInstance(TestXML.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            TestXML testXMLs = (TestXML) unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

and the testXML class

@XmlRootElement(name="rss")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestXML {   
    public TestXML() {
    }

    @XmlElementWrapper(name="channel")
    @XmlElement(name="item")
    private int i ;

    public int getI() {
        return i;
    }    
    public void setI(int i) {
        this.i = i;
    }
}

BTW: In my case it was

<dependency>
    <groupId>jcs</groupId>
    <artifactId>jcs</artifactId>
    <version>1.3</version>
</dependency>

Hope that helps.

mmx73
  • 972
  • 1
  • 8
  • 19
  • 1
    This is a useful process that you describe. But it would also be useful to get information about which dependency that caused this error in your case! – Lii Nov 03 '14 at 14:56
  • @Lii In my case it was the java caching system jcsjcs1.3 – mmx73 Nov 03 '14 at 18:34
  • 2
    > "Maybe someone has a better (more professional) method" That'd be using the Maven dependency plugin and simply looking for Xerces. `org.apache.maven.plugins:maven-dependency-plugin:2.10:tree` – Abhijit Sarkar Jan 25 '16 at 21:09
5

An implementation of JAXB has been included in Java SE since version 6. If you remove the Maven dependency (which is probably causing a version conflict), everything should work.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Mhhh ... thanks, as I was desperate I added the dependency to solve the problem but nothing changed. I removed it but still the same result. I edited my question. – mmx73 Sep 03 '14 at 14:23
  • @mmx73 - Do you see the same issue when you run the example without Maven? – bdoughan Sep 03 '14 at 15:05
  • Do you think its a dependency problem ? Maybe I can set up a simple projekt just running a small XML parser programme. I will try this on the weekend and come back. – mmx73 Sep 05 '14 at 14:46
  • @mmx73 - Yes I expect this is a dependency problem. – bdoughan Sep 05 '14 at 14:47
  • Ok, mhmm .... maybe i should try to upgrade all my dependecies to the latest release version, there are loads of packages linked to that project. – mmx73 Sep 05 '14 at 14:52
  • 1
    @blaise_doughan : your were right, it was a dependency problem. I will answer my question on my own with my solution how I found out. Thanks for your help. – mmx73 Sep 12 '14 at 09:43
5

Both Bernard and Blaise's answers were very helpful. In my case, since I am using JDK 7, the solution was to exclude the xerces subdependency that was being included by one of my dependencies:

<dependency>
  <groupId>org.apache.axis</groupId>
  <artifactId>axis</artifactId>
  <version>1.4.1-SNAPSHOT</version>
  <exclusions>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xmlParserAPIs</artifactId>
    </exclusion>
  </exclusions>
</dependency>
pimlottc
  • 3,066
  • 2
  • 29
  • 24
3

I resolved this problem on my project with the second Mitch ‘solution but just with

java -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
foxpaps
  • 41
  • 3
  • It solve my problem, we use jdk6 to compile and run with tomcat6 & jdk8. It's great that no need any code related change. – meadlai Jun 14 '17 at 04:03
1

Using SAXparser can be a nightmare. This is the most widely used XML parser in java and every one have end up using either directly or indirectly. JDK 8 have JAXB already available . So if you are using JDK 8 then only possible way should be removing the maven dependency. I had this issue as well so I tried removing the maven dependency but not happened. Then I thought why not revert to older version if java and VOILLA I got success. I am using jdk 7 currently and my tests run smoothly. I guess this is the only solution.

Naveen Kumar
  • 189
  • 2
  • 5
1

Try to create a XML Document and unmarshal it. It was worked for me. JAXBContext jc = JAXBContext.newInstance( Message.class );

        InputStream stream = new ByteArrayInputStream( string.getBytes( StandardCharsets.UTF_8 ) );
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse( stream );

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Message msg = ( Message ) unmarshaller.unmarshal( doc );
madhugeeth
  • 11
  • 1
  • As mentioned below it was/is a dependency problem, in my case with jcs. So plain vanilla the code always works well. – mmx73 Oct 30 '15 at 14:41
0

We also met the issue and noticed that you need to keep the jdk version and jre version the same, otherwise will exist the version mismatch caused the issue.

The guys who met the issue use jdk1.6 and jre 1.8, when changed to both jdk1.6, the issue gone.

James Liu
  • 1
  • 2
0

I had faced similar issue, this issue occurs when there is big difference in versions of xerces jar and xercesImpl jar. To solve this, I used xerces-2.9.0 and xercesImpl-2.9.1 and the issue gone.

Mahendra Andhale
  • 489
  • 8
  • 14
0

I had a similar issue while trying to solve the sonar vulnerability java:S2755.

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // added (for sonar)
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // added (for sonar)

After adding those two lines the first setProperty() call threw a SAXNotRecognizedException.

I guess this happened because there were multiple implementations available of XMLSchemaFactory, one of them being included in the JDK.

My solution was to run mvn dependency:tree on the project and search for any occurences of "xerces". I found two dependencies which I excluded from all dependencies that used them:

<dependency>
    <!-- ... -->
    <exclusions>
        <exclusion>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <!-- ... -->
    <exclusions>
        <exclusion>
            <groupId>com.rackspace.apache</groupId>
            <artifactId>xerces2-xsd11</artifactId>
        </exclusion>
    </exclusions>
</dependency>
0

I had the same issue and was fixed by setting JVM arguements as -Djavax.xml.accessExternalDTD=all -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl

rslj
  • 330
  • 1
  • 3
  • 13