web-dev-qa-db-ja.com

どのJAXP実装が使用されており、どこからロードされたかを確認するにはどうすればよいですか?

使用されている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を作成せずに、これを達成するためのより良い方法はありますか?

30
Daniel Fortunov

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

公式JAXP FAQ (質問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
54
Daniel Fortunov

追加するだけです

-Djaxp.debug=1

to Java_OPTSそしてあなたはそのような情報を見るでしょう。

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

8
trang

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

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

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

4
zg_spring

「フォールバックプラットフォームのデフォルト実装」の前に検索される別の場所があります。それはJava.endorsed.dirsディレクトリ Java Endorsed Standards Override Mechanism

承認済み標準オーバーライドメカニズムは、承認済み標準またはスタンドアロンテクノロジを実装するクラスおよびインターフェイスの新しいバージョンをJavaプラットフォームに組み込むことができる手段を提供します。

1
jwd630

状況によって異なりますが、通常はありません。

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

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

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

1
jarnbjo