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

11

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

我用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);
        }

    }

我的目标是应用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。

xercesImpl-2.8.0.jar:?? 你的 Web 应用程序中是否有 Xerces 的副本? - nitind
是的,我有。我甚至尝试在Eclipse构建路径部分更改优先级,使用XercesImpl在JRE系统库之前。 - Bia
这可能适用于普通的Java应用程序,但Tomcat必须从您的Web应用程序的JAR文件中加载类。那样的技巧行不通。 - nitind
您可以在此帖子中查看提供的答案。 - Chamlal
4个回答

11

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

或者,由于JDK包含了Xerces的实现,您可以使用System.properties配置DocumentBuilderFactory返回JDK版本。进行配置

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

这与https://dev59.com/SVcO5IYBdhLWcg3w3VAc相关,因此避免使用xerces并设置DocumentBuilderFactory也可能有所帮助,这在我的情况下确实起了作用。 - Gregor

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

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: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized. at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(Unknown Source)...”的错误。
长话短说,解决方案是把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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接