Java 如何使用 logback 禁用 accessExternalDTD 和 entityExpansionLimit 警告

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25453042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:26:28  来源:igfitidea点击:

How to disable accessExternalDTD and entityExpansionLimit warnings with logback

javagroovylogbacksaxparserxerces2-j

提问by msoori

I'm using logback with groovy and get lots of warnings showing up when parsing xml. I am aware of the bug in JDK1.7_u45 that is causing this.

我正在使用带有 groovy 的 logback,并且在解析 xml 时出现了很多警告。我知道导致此问题的 JDK1.7_u45 中的错误。

Warning:  org.apache.xerces.parsers.SAXParser: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
Warning:  org.apache.xerces.parsers.SAXParser: Property 'http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit' is not recognized.

Is there any way to turn off this log warnings from showing up in DEBUG? I tried writing a filter using Filter, but didn't help.

有什么方法可以关闭此日志警告,使其不显示在 DEBUG 中?我尝试使用过滤器编写过滤器,但没有帮助。

回答by 6ton

This is a known bug in the JRE that reports this as an warning. See bug reports hereand here

这是 JRE 中的一个已知错误,将其报告为警告。在此处此处查看错误报告

The issue happens only when you have xerces jar in your classpath, the xerces implementation does not recognize the property and throws an exception on org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.setProperty()which results in a warning log (to System.err) from the com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.parse()

仅当您的类路径中有 xerces jar 时才会发生此问题,xerces 实现无法识别该属性并在org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.setProperty()上引发异常,从而导致警告日志(到 System .err) 来自com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.parse()

The easy (if possible) solution is remove xerces jar from your classpath.

简单(如果可能)的解决方案是从类路径中删除 xerces jar。

Your log filter does not work since the error is never sent to slf4j. Which kind of suggests a convoluted way of fixing the issue - redirect System.err to slf4jand then use a logging filter on it.

您的日志过滤器不起作用,因为错误从未发送到 slf4j。哪种建议解决问题的复杂方法 - 将System.err重定向到 slf4j,然后在其上使用日志过滤器。

Sample code to reproduce the issue (based on the issue report):

重现问题的示例代码(基于问题报告):

import java.io.IOException;
import java.net.URL;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;

public class XercesTest {
    public static void main(String[] args) throws IOException, TransformerConfigurationException {
        TransformerFactory tf = TransformerFactory.newInstance();
        URL xsl = MainClass.class.getResource("build.xsl");
        StreamSource stylesheetSource = new StreamSource(
            xsl.openStream(), xsl.toExternalForm());
        tf.newTransformer(stylesheetSource);
    }
}

build.xsl

构建.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <!-- TODO: Auto-generated template -->
    </xsl:template>
</xsl:stylesheet>

And maven dependency:

和 maven 依赖:

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
</dependency>

回答by Dana Britzman

I also had this error in a project. As I understand it, newer versions of the JRE have the Xerces implementation built into it. More importantly, the JRE version properly supports the accessExternalDTDand entityExpansionLimitproperties.

我在一个项目中也有这个错误。据我了解,较新版本的 JRE 内置了 Xerces 实现。更重要的是,JRE 版本正确支持accessExternalDTDentityExpansionLimit属性。

Because I had a downstream dependency that was including xercesImpl.jarin my war file, my solution was to just yank it using the code below in my build.gradleand let the JRE implementation of xerces take over in the class path.

因为我有一个包含xercesImpl.jar在我的 war 文件中的下游依赖项,我的解决方案是在我的代码中使用下面的代码猛拉它,build.gradle并让 xerces 的 JRE 实现在类路径中接管。

warApplication {
    from '/WEB-INF/lib'
        exclude 'xercesImpl*.jar'
}

回答by David Burstr?m

If it is not possible to remove xerces from the classpath, you can be more explicit about which factory you want to use, thus avoiding pulling in xerces. Here are two ways of resolving specific factories:

如果无法从类路径中删除 xerces,您可以更明确地说明要使用哪个工厂,从而避免拉入 xerces。以下是解决特定工厂的两种方法:

public static SchemaFactory getSchemaFactory() {
  return schemaFactory =
    SchemaFactory.newInstance(
        "http://www.w3.org/2001/XMLSchema",
        "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory",
        null);
}

public static TransformerFactory getTransformerFactory() {
  try {
    final Class<?> transformerFactoryImplClass =
      TransformerFactory.class
          .getClassLoader().loadClass("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
    final Method factoryGetter =
      transformerFactoryImplClass.getDeclaredMethod("newTransformerFactoryNoServiceLoader");
    return (TransformerFactory) factoryGetter.invoke(null);
  } catch (ClassNotFoundException
    | NoSuchMethodException
    | IllegalAccessException
    | InvocationTargetException e) {
    // fallback in case com.sun.* is not available
    return TransformerFactory.newInstance();
  }
}