TransformerFactory 和 Xalan 依赖冲突
Posted
技术标签:
【中文标题】TransformerFactory 和 Xalan 依赖冲突【英文标题】:TransformerFactory and Xalan Dependency Conflict 【发布时间】:2017-12-22 11:46:54 【问题描述】:我有以下代码:
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 保留为依赖项的情况下解决此冲突?
【问题讨论】:
为什么需要 Xalan 依赖项? Xalan 从 JDK 1.4 开始就得到认可。正常情况下不需要。 我正在制作一个对每个 Java XML 解析器都有单元测试的 Web 应用程序。 【参考方案1】:需要如下设置系统级属性
System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
【讨论】:
这个解决方案是最后帮助我的唯一解决方案,谢谢! 这个解决方案有效,有人能解释为什么吗?? @rahul 之所以有效,是因为无论 JDK 的哪个版本,它都开始支持 JAXP 1.5。 Xerces 仅支持 1.4。通过设置此属性,您可以指定实现类实际上应该是来自 JDK 的实现类。只要您不使用不提供此类的其他 JDK(例如 IBM JDK),这很好。【参考方案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>
【讨论】:
我已经排除了 xerces 库,但仍然遇到同样的错误。我怎么知道还有什么可能与 TransformerFactory 发生冲突? 与@DavidChampion 一样,还有其他解决方案吗?【参考方案3】:如果您是多个 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 设置属性。
【讨论】:
通过使用此解决方案,Sonar 仍然不满意,并将其突出显示为 Blocker 说“xml 解析器不应受到 xxe 攻击”【参考方案4】:对我有用的解决方案是这样做:
compile('org.opensaml:opensaml:2.6.1')
exclude group: 'xerces', module: 'xercesImpl'
exclude module: 'xalan'
【讨论】:
【参考方案5】:它可能来自您项目的其他 xalan 版本。
在您的 POM 中检查 xalan 的 Dependent Hierarchy,并在所有 xalan 版本中排除 xercesImpl。
【讨论】:
请尝试在评论部分限制可能性。我们需要验证它。所以应该在评论区。谢谢【参考方案6】:我遇到了类似的问题,在 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,您必须为其他版本找到正确的包。
【讨论】:
以上是关于TransformerFactory 和 Xalan 依赖冲突的主要内容,如果未能解决你的问题,请参考以下文章
是否可以避免使用 xalan TransformerFactory?
如何防止特征 FEATURE_SECURE_PROCESSING 设置为 true 的 TransformerFactory 剥离属性?
如何在 Java 中选择撒克逊 TransformerFactory
要求在多线程环境中明确 TransformerFactory 的 XSLT Transformer
如何防止具有 META-INF\services\javax.xml.transform.TransformerFactory 的 xalan.jar 接管 Xalan 实现中内置的 JDK 1.6?
weblogic 12c下jxls导出excel报错Could not initialize class org.apache.poi.xssf.usermodel.XSSFVMLDrawing