使用されている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
を作成せずに、これを達成するためのより良い方法はありますか?
実装を選択するプロセスのため、実際にインスタンスを作成せずに、どの具体的なJAXPファクトリ実装がロードされるかを予測することは非常に困難です。
公式JAXP FAQ (質問14)から:
アプリケーションが新しいJAXP
DocumentBuilderFactory
インスタンスを作成する場合、staicメソッドDocumentBuilderFactory.newInstance()
を呼び出します。これにより、次の順序を使用してDocumentBuilderFactory
の具象サブクラスの名前が検索されます。
javax.xml.parsers.DocumentBuilderFactory
のようなシステムプロパティが存在し、アクセス可能である場合の値。- ファイルの内容
$Java_HOME/jre/lib/jaxp.properties
(存在する場合)。- Jarファイル仕様で指定されているJarサービスプロバイダーの検出メカニズム。 jarファイルには、インスタンス化する具象クラスの名前を含む
META-INF/services/javax.xml.parsers.DocumentBuilderFactory
などのリソース(つまり、埋め込みファイル)を含めることができます。- フォールバックプラットフォームのデフォルトの実装。
この複雑さに加えて、個々の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
追加するだけです
-Djaxp.debug=1
to Java_OPTS
そしてあなたはそのような情報を見るでしょう。
詳細: https://docs.Oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html
簡単です、設定するだけです
System.setProperty("jaxp.debug", "1");
トラックは、whickimplとwhickwayjaxpの使用法を教えてくれます。
「フォールバックプラットフォームのデフォルト実装」の前に検索される別の場所があります。それはJava.endorsed.dirs
ディレクトリ Java Endorsed Standards Override Mechanism
承認済み標準オーバーライドメカニズムは、承認済み標準またはスタンドアロンテクノロジを実装するクラスおよびインターフェイスの新しいバージョンをJavaプラットフォームに組み込むことができる手段を提供します。
状況によって異なりますが、通常はありません。
DocumentBuilderFactory.newInstance()
は、システムプロパティ「javax.xml.parsers.DocumentBuilderFactory」で設定されているDocumentBuilderFactory
の実装を返すか、システムプロパティが設定されていない場合はJREのデフォルトファクトリを返します。デフォルトのファクトリは、newInstanceメソッドの実装でハードコードされている可能性が高く、他の方法ではアクセスできません。
システムプロパティが設定されている場合は、少なくとも関連するクラスローダーでgetResourceメソッドを使用してURLを取得し、そこからクラスローダーが対応するクラスファイルをロードすることができます。 jarファイルからのものである場合は、jar:URLからファイル名(またはソースURL)を抽出できるはずです。クラスパスからメタデータファイルを手動で読み取る場合は、詳細なパッケージ情報も利用できるはずです。
システムプロパティが設定されていない場合は、すでに行っているように実際に新しいファクトリを作成せずに、探している情報を取得する方法はないと確信しています。