Java 和 Xerces:找不到属性 XMLConstants.ACCESS_EXTERNAL_DTD

问题描述 投票:0回答:5

我在这个博客上查找了类似的帖子,但找不到我的问题的答案,所以我决定寻求帮助。

我用 Java 编写了这个简单的函数:

 public void open(InputStream stream) throws FoliumFatalException {
        try {
            InputSource is = new InputSource(stream);
            DocumentBuilderFactory dfact = DocumentBuilderFactory.newInstance();
            
//            /* OWASP: inhibit access to External Entities */
            dfact.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); 
            dfact.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); 
            
            _doc = dfact.newDocumentBuilder().parse(is);

        } catch (Throwable t) {
            _logger.error(t, t);
            throw new FoliumFatalException("ENG-0017", "Errore di parsing su stream", t);
        }

    }

我的目标是应用here公开的 OWASP 标准,但我收到以下错误:

 java.lang.IllegalArgumentException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
java.lang.IllegalArgumentException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
    at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(Unknown Source) ~[xercesImpl-2.8.0.jar:?]
    at agora.folium.engine.impl.j2ee.FoliumJ2eeXmlParserImpl.open(FoliumJ2eeXmlParserImpl.java:108) [classes/:?]
    at agora.folium.engine.impl.FoliumAbstractEngine.loadServices(FoliumAbstractEngine.java:268) [classes/:?]
    at agora.folium.engine.impl.j2ee.FoliumJ2eeEngineImpl.startup(FoliumJ2eeEngineImpl.java:110) [classes/:?]
    at agora.folium.engine.Folium.startup(Folium.java:258) [classes/:?]
    at agora.folium.control.impl.j2ee.FoliumActionServlet.init(FoliumActionServlet.java:94) [classes/:?]
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1230) [catalina.jar:7.0.85]
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1174) [catalina.jar:7.0.85]
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1066) [catalina.jar:7.0.85]
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5370) [catalina.jar:7.0.85]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5668) [catalina.jar:7.0.85]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) [catalina.jar:7.0.85]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1015) [catalina.jar:7.0.85]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:991) [catalina.jar:7.0.85]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652) [catalina.jar:7.0.85]
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:712) [catalina.jar:7.0.85]
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:2002) [catalina.jar:7.0.85]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_141]
    at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_141]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_141]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_141]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_141]

我正在使用 Eclipse Oxygen、Tomcat 7 和 Java 1.8。

java eclipse tomcat xerces
5个回答
11
投票

javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
JAXP 1.5中定义,但Xerces不支持它。如果无法删除 Xerces 依赖项,则应在 Xerces 之前将另一个实现添加到类路径中。

或者,由于 JDK 包含 Xerces 的实现,您可以使用 DocumentBuilderFactory

configure
System.properties
返回 JDK 版本。

System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
        "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");

6
投票

该问题是由于类路径中的 Xerces/XercesImpl 引起的。 Xerces 不提供对 ACCESS_EXTERNAL_DTD 属性的支持。

解决方案 1. 如果可能,从类路径中删除 xerces jar。

解决方案2.使用JDK默认实现

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", null);


3
投票

Apache Xerces-J 2.12.0 及更早版本实现的旧版本 JAXP 不支持您尝试设置的任一属性。要阻止对外部实体的访问,您可以编写一个 EntityResolver(始终抛出 SAXException)并向 DocumentBuilder 注册该 EntityResolver。请参阅此处的文档 [1]。

[1] http://xerces.apache.org/xerces2-j/javadocs/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver(org.xml.sax.EntityResolver)


0
投票

我们的 Java 项目是使用 Maven 构建的。当团队决定将 SonarQube 集成到管道中时,我们遇到了类似的情况。 “SonarQube 不会运行您的测试或生成报告。它仅导入预先生成的报告”(更多信息此处)。对于 Java/Kotlin/Scala/JVM,SonarQube 需要一些“JaCoCo XML 覆盖率报告”。因此,我们必须向 pom.xml 添加依赖项:

<dependency>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>${jacoco.version}</version>
</dependency>

经过一些调整后,我们一切都启动并运行了。但某些测试因“java.lang.IllegalArgumentException:无法识别属性'http://javax.xml.XMLConstants/property/accessExternalDTD'”而失败。 在 org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(来源未知)...”。

长话短说,解决方案是将 xerces 排除在外,正如其他答案中已经指出的那样:

<dependency>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>${jacoco.version}</version>
  <exclusions>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
    </exclusion>
  </exclusions>
</dependency>

0
投票

对于在迁移到 Java 17 时遇到此问题的任何人,使用 Maven 排除从类路径中删除 Xerces 可能不是一个选择。 JEP-403 在“风险和假设”下明确说明了以下内容:

“使用 Xerces XML 处理器的 JDK 内部副本的代码。此类代码应使用 Xerces 库的独立副本,可从 Maven Central 获取。” (否则,这样的代码可能会失败) https://openjdk.org/jeps/403

因此,如果您正在使用这些属性中的一个或两个并且需要迁移到Java 17,不确定这个问题的解决方案是什么......

© www.soinside.com 2019 - 2024. All rights reserved.