36

どのJAXP実装が使用されているか、およびどのJARファイルからロードされたかについての診断情報を提供したいと思います。

これを実現する1つの方法は、たとえば、のインスタンスを作成してから、DocumentBuilderFactoryそのクラスのプロパティを検査することです。

private static String GetJaxpImplementation() {
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    Class<? extends DocumentBuilderFactory> c = documentBuilderFactory.getClass();
    Package p = c.getPackage();
    CodeSource source = c.getProtectionDomain().getCodeSource();
    return MessageFormat.format(
            "Using JAXP implementation ''{0}'' ({1}) version {2} ({3}){4}",
            p.getName(),
            p.getImplementationVendor(),
            p.getSpecificationVersion(),
            p.getImplementationVersion(),
            source == null ? "." : " loaded from: " + source.getLocation());
}

おそらく作成する必要なしに、これを達成するためのより良い方法はありDocumentBuilderFactoryますか?

4

5 に答える 5

62

実装を選択するプロセスのため、実際にインスタンスを作成せずに、どの具体的なJAXPファクトリ実装がロードされるかを予測することは非常に困難です。

公式JAXPFAQ(質問14)から:

アプリケーションが新しいJAXPDocumentBuilderFactory インスタンスを作成する場合、staicメソッドを呼び出します DocumentBuilderFactory.newInstance()DocumentBuilderFactoryこれにより、次の順序を使用して具体的なサブクラスの名前が検索され ます。

  1. javax.xml.parsers.DocumentBuilderFactoryシステムプロパティが存在し、アクセス可能であるかどうかなどのシステムプロパティの値。
  2. ファイル$JAVA_HOME/jre/lib/jaxp.propertiesが存在する場合はその内容。
  3. Jarファイル仕様で指定されているJarサービスプロバイダーの検出メカニズム。jarファイルにはMETA-INF/services/javax.xml.parsers.DocumentBuilderFactory、インスタンス化する具象クラスの名前などのリソース(つまり、埋め込みファイル)を含めることができます。
  4. フォールバックプラットフォームのデフォルトの実装。

この複雑さに加えて、個々のJAXPファクトリは独立した実装を指定できます。1つのパーサー実装と別のXSLT実装を使用するのが一般的ですが、上記の選択メカニズムの粒度により、さらに高度に混合および一致させることができます。

次のコードは、4つの主要なJAXPファクトリに関する情報を出力します。

private static void OutputJaxpImplementationInfo() {
    System.out.println(getJaxpImplementationInfo("DocumentBuilderFactory", DocumentBuilderFactory.newInstance().getClass()));
    System.out.println(getJaxpImplementationInfo("XPathFactory", XPathFactory.newInstance().getClass()));
    System.out.println(getJaxpImplementationInfo("TransformerFactory", TransformerFactory.newInstance().getClass()));
    System.out.println(getJaxpImplementationInfo("SAXParserFactory", SAXParserFactory.newInstance().getClass()));
}

private static String getJaxpImplementationInfo(String componentName, Class componentClass) {
    CodeSource source = componentClass.getProtectionDomain().getCodeSource();
    return MessageFormat.format(
            "{0} implementation: {1} loaded from: {2}",
            componentName,
            componentClass.getName(),
            source == null ? "Java Runtime" : source.getLocation());
}

次のサンプル出力は、3つの異なるJAXP実装(組み込みのXercesとXerces 2.8およびXalan用の外部JAR)の組み合わせを示しています。

DocumentBuilderFactory implementation: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xerces-2.8.0.jar
XPathFactory implementation: com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl loaded from: Java Runtime
TransformerFactory implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xalan.jar
SAXParserFactory implementation: org.apache.xerces.jaxp.SAXParserFactoryImpl loaded from: file:/C:/Projects/Scratch/lib/xerces-2.8.0.jar
于 2009-11-26T15:22:27.777 に答える
13

追加するだけ

-Djaxp.debug=1

にするJAVA_OPTSと、そのような情報が表示されます。

詳細: https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html

于 2014-12-15T02:56:46.820 に答える
4

簡単です、設定するだけです

System.setProperty("jaxp.debug", "1");

トラックは、whickimplとwhickwayjaxpの使用法を教えてくれます。

于 2012-12-11T03:10:06.097 に答える
1

場合によりますが、一般的にはありません。

DocumentBuilderFactory.newInstance()DocumentBuilderFactoryシステム プロパティ「javax.xml.parsers.DocumentBuilderFactory」で構成されている実装を返すか、システム プロパティが設定されていない場合は JRE のデフォルト ファクトリを返します。デフォルトのファクトリは、newInstance メソッドの実装でハードコードされている可能性が高く、それ以外の場合はアクセスできません。

システム プロパティが設定されている場合、少なくとも関連するクラス ローダーで getResource メソッドを使用して URL を取得できます。この URL から、クラス ローダーは対応するクラス ファイルをロードします。jar ファイルからのものである場合は、jar: URL からファイル名 (またはソース URL) を抽出できるはずです。クラスパスからメタデータファイルを手動で読み取ると、詳細なパッケージ情報も利用できるはずです。

システム プロパティが設定されていない場合、すでに行っているように、実際に新しいファクトリを作成しない限り、探している情報を取得する方法はないと確信しています。

于 2009-11-25T18:12:40.487 に答える