TransformerFactory和Xalan依赖冲突

时间:2017-07-17 20:02:03

标签: java xml maven xalan

我有以下代码:

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

这通常很好。但是,我还需要在我的pom.xml中添加Xalan作为依赖项,当我这样做时,上面的代码现在抛出一个错误:

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

我认为这与Xalan的jar在其中有不同的Transformer实现有关。如何在不更改上述代码并将Xalan保持为依赖的情况下解决此冲突?

6 个答案:

答案 0 :(得分:2)

从Xalan中排除Xerces解决了这个问题:

<dependency>
    <groupId>xalan</groupId>
    <artifactId>xalan</artifactId>
    <version>2.7.2</version>
    <exclusions>
        <exclusion>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
        </exclusion>
    </exclusions>
</dependency>

答案 1 :(得分:0)

如果您是多个XSL处理器或不同版本,则必须处理并非每个实现都能够处理每个属性的情况。唯一的方法是捕获在不支持该属性时抛出的IllegalArgumentException。请查看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
}

文档说:

  

当可以进行代码更改时,对于新开发,建议按照上面的说明设置新属性。通过这种方式设置属性,应用程序可以确保维护所需的行为,无论它们是部署到较旧版本还是较新版本的JDK,还是通过“系统属性”或jaxp.properties设置属性。

答案 2 :(得分:0)

对我有用的解决方案是这样做:

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

答案 3 :(得分:0)

它可能来自您项目的其他xalan版本。

在POM中检查xalan的从属层次结构,并在所有xalan版本中排除xercesImpl。

答案 4 :(得分:0)

我遇到了类似的问题,即在TransformerFactory::newInstance中创建了SaxonJ的实现,在尝试设置它不支持的属性时出现了错误。

看看method documentation,我发现TransformerFactory有一个优先级列表,它试图在其中找到要返回的实现。

它要查找的第一个位置是系统属性,因此在我的Ant文件的运行目标中,添加了以下内容(其他库将具有相同的内容):

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

这将使TransformerFactory :: newInstance加载正确的工厂实现。

请记住,我使用的是OpenJDK8,您将必须找到其他版本的正确软件包。

答案 5 :(得分:0)

需要如下设置系统级属性

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