Подтвердить что ты не робот

Как отключить accessExternalDTD и сущностьExpansionLimit предупреждения с записью

Я использую logback с groovy и получаю много предупреждений, возникающих при анализе 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.

Есть ли способ отключить предупреждения журнала из DEBUG? Я попытался написать фильтр с помощью фильтра, но не помог.

4b9b3361

Ответ 1

Это известная ошибка в JRE, которая сообщает об этом как предупреждение. См. Отчеты об ошибках здесь и здесь

Проблема возникает только тогда, когда у вас есть xerces jar в вашем пути к классам, реализация xerces не распознает свойство и генерирует исключение в org.apache.xerces. jaxp.SAXParserImpl $JAXPSAXParser.setProperty(), в результате чего появляется журнал предупреждений (в System.err) из com.sun.org.apache. xalan.internal.xsltc.compiler.Parser.parse()

Простым (если возможно) решением является удаление xerces jar из вашего пути к классам.

Фильтр журнала не работает, поскольку ошибка никогда не отправляется на slf4j. Какой тип предлагает сложный способ исправления проблемы - перенаправить System.err на slf4j, а затем использовать на нем фильтр регистрации.

Пример кода для воспроизведения проблемы (на основе отчета о проблеме):

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

<?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>

И зависимость maven:

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

Ответ 2

Один из способов взломать это - просто отключить эти сообщения из стандартных потоков вывода/ошибок. Я создал XercesWarningFilter, чтобы выполнить это. Просто включите это в свой путь к классу, а затем запустите при запуске следующее: эти сообщения будут подавлены:

XercesWarningFilter.start();

Ответ 3

У меня также была эта ошибка в проекте. Насколько я понимаю, в новых версиях JRE реализована реализация Xerces. Что еще более важно, версия JRE правильно поддерживает свойства accessExternalDTD и entityExpansionLimit.

Поскольку у меня была зависимая от нисходящего потока, которая включала xercesImpl.jar в моем военном файле, мое решение состояло в том, чтобы просто выдернуть ее, используя код ниже в моем build.gradle, и пусть реализация xerces JRE возьмет верх в пути класса.

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

Ответ 4

Если невозможно удалить 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();
  }
}