Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TransformerFactory and Xalan Dependency Conflict

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?

like image 435
Velvet Carrot Avatar asked Jul 17 '17 20:07

Velvet Carrot


3 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");
like image 140
user2646103 Avatar answered Oct 19 '22 12:10

user2646103


Excluding Xerces from Xalan fixes this issue:

<dependency>
    <groupId>xalan</groupId>
    <artifactId>xalan</artifactId>
    <version>2.7.2</version>
    <exclusions>
        <exclusion>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
        </exclusion>
    </exclusions>
</dependency>
like image 4
Velvet Carrot Avatar answered Oct 19 '22 11:10

Velvet Carrot


If you are multiple XSL processors and or different versions, you have to handle the case that not every implementation will be able to handle every attribute. The only way to do so is to catch the IllegalArgumentException that is thrown if the attribute is not supported. Take a look at this modified example from the JAXP documentation:

javax.xml.transform.TransformerFactory factory = TransformerFactory.newInstance();

try {
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
} catch (IllegalArgumentException e) {
    //jaxp 1.5 feature not supported
}

The documentation says:

When code change is possible, and for new development, it is recommended that the new properties be set as demonstrated above. By setting the properties this way, applications can be sure to maintain the desired behavior whether they are deployed to older or newer version of the JDK, or whether the properties are set through System Properties or jaxp.properties.

like image 2
fhossfel Avatar answered Oct 19 '22 11:10

fhossfel