TransformerFactory and Xalan Dependency Conflict

Viewed 24353

I have the following code:

javax.xml.transform.TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
javax.xml.transform.Transformer transformer = factory.newTransformer();

This works fine normally. However, I also need to add Xalan as a dependency in my pom.xml, and when I do, the above code now throws an error:

java.lang.IllegalArgumentException: Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD

I think it has something to do with the fact that Xalan's jar has a different implementation of Transformer in it. How can I resolve this conflict without changing the above code and keeping Xalan as a dependency?

7 Answers

Need to set the system-level property as below

System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");

I was facing a similar issue where an implementation from SaxonJ was being created in TransformerFactory::newInstance, giving me errors when trying to set attributes not supported by it.

Taking a look at the method documentation, I found out that TransformerFactory has a priority list where it tries to find an implementation to return.

The first place it looks for is in the system properties, so in my Ant file, inside my run target, I added the following(other libraries will have the same):

<jvmarg value="-Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"/>

This will make TransformerFactory::newInstance load the correct factory implementation.

Keep in mind that I was using OpenJDK8, you will have to find the correct package for other versions.

The solution that worked for me was by doing this:

compile('org.opensaml:opensaml:2.6.1') {
    exclude group: 'xerces', module: 'xercesImpl'
    exclude module: 'xalan'
}

It might be coming from other xalan version of your project.

Check Dependent Hierarchy in your POM for the xalan and exclude the xercesImpl in all the version of xalan.

This happens to my code because I am using xalan's transformer factory from external dependency.

TransformerFactory factory = TransformerFactory.newInstance();

I just specified that I will use the internal jars provided by AdoptOpenJdk

TransformerFactory factory = TransformerFactory.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl", null);
Related