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.
このログの警告をDEBUGに表示しないようにする方法はありますか? Filterを使用してフィルターを作成しようとしましたが、助けにはなりませんでした。
これは、これを警告として報告するJREの既知のバグです。バグレポートを参照してください here および here
この問題は、クラスパスにxerces jarがある場合にのみ発生し、xerces実装はプロパティを認識せず、 org.Apache.xerces.jaxp.SAXParserImpl $ JAXPSAXParser.setProperty() で例外をスローします com.Sun.org.Apache.xalan.internal.xsltc.compiler.Parser.parse() からの警告ログ(System.errへ)
簡単な(可能な場合)ソリューションは、クラスパスからxerces jarを削除することです。
エラーはslf4jに送信されないため、ログフィルターは機能しません。どのような種類の問題を解決する複雑な方法を示唆しています- System.err to 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
プロパティを適切にサポートしていることです。
WarファイルにxercesImpl.jar
を含むダウンストリーム依存関係があったため、私のソリューションはbuild.gradle
で以下のコードを使用してヤンクし、クラスパスでxercesのJRE実装を引き継ぐことでした。
warApplication {
from '/WEB-INF/lib'
exclude 'xercesImpl*.jar'
}
クラスパスからxercesを削除できない場合は、使用するファクトリをより明確にすることができるため、xercesのプルを回避できます。特定の工場を解決する2つの方法を次に示します。
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();
}
}