java - 在使用和加载它的位置上,java如何确定哪个JAXP实现是?

  显示原文与译文双语对照的内容
87 3

我想提供关于JAXP实现正在使用的诊断信息以及它从哪个 jar 文件加载的诊断信息。

实现这里目的的一种方法是在实例中创建一个 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

时间: 原作者:

63 0

如果不实际创建一个实例,就很难预测具体的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工厂都可以有一个独立的实现。 通常使用一个解析器实现和另一个XSLT实现,但上面的选择机制的粒度允许你进行混合。

以下代码将输出关于四个主要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());


}



以下示例输出为以下示例提供了三个不同JAXP实现的mix-and-match的示例:


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



...