Как отключить предупреждения accessExternalDTD и entityExpansionLimit с выходом из системы

Я использую 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? Я попытался написать фильтр, используя фильтр, но не помог.

5 ответов

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

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

Самое простое (если возможно) решение - убрать банку xerces из вашего classpath.

Ваш фильтр журнала не работает, так как ошибка никогда не отправляется на 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>

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

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

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

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

Старый вопрос, который я знаю, просто хотел опубликовать ярлык. Как упоминалось в ответе Даны Бритцман, в новые версии JRE встроены реализации Xerces и Xalan. Что еще более важно, версия JRE правильно поддерживает свойства accessExternalDTD и entityExpansionLimit.

Мне нужна была реализация xalan, и я сделал, как показано ниже

TransformerFactory tf = com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl", null);

Чтобы обойти это в последней версии JDK8, я использовал этот код:

        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", this.getClass().getClassLoader());

На внутренних упакованных классами являются частью JDK. Это гарантирует, что он использует классы JDK и не будет пытаться использовать какие-либо другие версии, которые существуют (например, что происходит с сервером Weblogic).

Другие вопросы по тегам