【发布时间】:2018-10-04 15:51:03
【问题描述】:
我有以下代码:
final TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
第二行在现代 JDK(我试过 1.8)中运行良好,默认为 TransformerFactory。但是,当我将 xalan(版本 2.7.2,最新版本)添加到类路径时,我在第二行得到以下信息:
Exception in thread "main" java.lang.IllegalArgumentException: Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD
at org.apache.xalan.processor.TransformerFactoryImpl.setAttribute(TransformerFactoryImpl.java:571)
at Main.main(Main.java:11)
我猜这是因为xalan 的TransformerFactory 不支持这个属性。 Xalan 的实现通过ServiceLoader 机制获取:在 xalan jar 中的services/javax.xml.transform.TransfomerFactory 中指定。
可以使用javax.xml.transform.TransformerFactory 系统属性或$JRE/lib/jaxp.properties 文件覆盖TransformerFactory 实现,或直接在代码中传递类名。但要做到这一点,我必须提供一个具体的类名。现在是com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl,但是在系统属性中硬编码它有点吓人,因为在JDK升级时他们可以很容易地更改类名,我们只会得到一个运行时错误。
有没有办法指示TransformerFactory.newInstance() 忽略 xalan 提供的实现?或者告诉它“只使用系统默认值”。
附:我不能只从类路径中删除xalan,因为我们使用的许多其他库都依赖于它。
【问题讨论】:
-
您是否要禁用此功能?如果是这样,请看这里:stackoverflow.com/questions/27128578/…
-
@trappski 是的,我正在尝试禁用外部 DTD 处理,所以我的问题看起来像是 X/Y 问题。但是
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)不会阻止 Xalan 访问外部 DTD:当我使用外部 DTD 链接(http 链接)提供 XML 时,Xalan 会尝试加载该 DTD 并获得ConnectException。