Как отключить 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? Я попытался написать фильтр с помощью фильтра, но не помог.
Ответы
Ответ 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();
}
}