TransformerFactory and Xalan Dependency Conflict
Asked Answered
T

7

13

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?

Taxation answered 17/7, 2017 at 20:2 Comment(2)
Why do you need the Xalan dependency? Xalan has been endorsed since JDK 1.4. Is is not necessary under normal circumstances.Ucayali
I'm making a web app that has unit tests for every Java XML parser.Taxation
T
5

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>
Taxation answered 17/7, 2017 at 21:17 Comment(2)
I have excluded the xerces library but still getting the same error. How can I know tell what else might be conflicting with TransformerFactory?Stout
Same as @DavidChampion, anyone else have another solution?Lippizaner
A
13

Need to set the system-level property as below

System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
Arleenarlen answered 15/10, 2020 at 3:41 Comment(4)
this solution was the only one that helped me in the end, thanks!Eccles
This solution works, could someone explain why??Heroworship
@rahul This works because since whatever version of JDK it started supporting JAXP 1.5. Xerces only supports 1.4. By setting this property you specify that the implementation class should actually be the one from the JDK. This is fine as long as you do not use a different JDK that does not provide this class, like IBM JDK.Kalie
I added this line of code in a static code block of the same class using the TransformerFactory but now I get this error in JUnit test cases javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found. Please help to resolve.Noreen
T
5

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>
Taxation answered 17/7, 2017 at 21:17 Comment(2)
I have excluded the xerces library but still getting the same error. How can I know tell what else might be conflicting with TransformerFactory?Stout
Same as @DavidChampion, anyone else have another solution?Lippizaner
K
4

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);
Keijo answered 29/7, 2022 at 8:59 Comment(2)
It worked for me, I preferred this solution over the one with more preferences https://mcmap.net/q/856751/-transformerfactory-and-xalan-dependency-conflict, less impact. Thank you.Hein
I use Saxon imlementation, and what it worked for me was: TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);Dowitcher
U
2

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.

Ucayali answered 17/7, 2017 at 21:22 Comment(1)
By using this solution, Sonar still not satisfied and highlight it as Blocker saying 'xml parsers should not be vulnerable to xxe attacks 'Uranium
L
1

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.

Lorenzoloresz answered 24/9, 2020 at 13:6 Comment(0)
H
0

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'
}
Homogenesis answered 21/5, 2019 at 19:22 Comment(0)
A
0

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.

Albric answered 30/5, 2019 at 12:26 Comment(1)
please, try limiting possibility in the comment section. We need to verify it. So it should be on the comment section. Thank youAtmometer

© 2022 - 2024 — McMap. All rights reserved.