web-dev-qa-db-ja.com

logExでaccessExternalDTDおよびentityExpansionLimit警告を無効にする方法

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を使用してフィルターを作成しようとしましたが、助けにはなりませんでした。

28
msoori

これは、これを警告として報告する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>
19
6ton

プロジェクトでもこのエラーが発生しました。私が理解しているように、JREの新しいバージョンにはXerces実装が組み込まれています。さらに重要なことは、JREバージョンがaccessExternalDTDおよびentityExpansionLimitプロパティを適切にサポートしていることです。

WarファイルにxercesImpl.jarを含むダウンストリーム依存関係があったため、私のソリューションはbuild.gradleで以下のコードを使用してヤンクし、クラスパスでxercesのJRE実装を引き継ぐことでした。

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

クラスパスから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();
  }
}
0
David Burström