Как отключить предупреждения 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).