如何找出正在使用的 JAXP 实现以及它是从哪里加载的?

Posted

技术标签:

【中文标题】如何找出正在使用的 JAXP 实现以及它是从哪里加载的?【英文标题】:How do I find out which JAXP implementation is in use and where it was loaded from? 【发布时间】:2009-11-25 16:58:28 【问题描述】:

我想提供有关正在使用的 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

【问题讨论】:

【参考方案1】:

在不实际创建实例的情况下,很难预测将加载哪些具体的 JAXP 工厂实现,因为选择实现的过程。

来自Official 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 实现(内置 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

【讨论】:

【参考方案2】:

只需添加

-Djaxp.debug=1

JAVA_OPTS,你会看到这样的信息。

更多详情:https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html

【讨论】:

【参考方案3】:

很简单,你只需设置

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

曲目会告诉你 whick impl 和 jaxp 的使用方式。

【讨论】:

【参考方案4】:

在“回退平台默认实现”之前搜索了另一个位置,即 java.endorsed.dirs 目录,如 Java Endorsed Standards Override Mechanism 中所述

认可的标准覆盖机制提供了一种方法,可以将实现认可标准或独立技术的类和接口的更高版本合并到 Java 平台中。

【讨论】:

从 8u40 开始 BTW 已弃用,您可以检查它是否仍在使用 -XX:+CheckEndorsedAndExtDirs【参考方案5】:

视情况而定,但一般不会。

DocumentBuilderFactory.newInstance() 将返回在系统属性“javax.xml.parsers.DocumentBuilderFactory”中配置的DocumentBuilderFactory 的实现,或者如果系统属性未设置,则返回 JRE 的默认工厂。默认工厂很可能在 newInstance 方法的实现中被硬编码,否则无法访问。

如果设置了系统属性,你至少可以使用相关类加载器上的getResource方法来获取URL,类加载器将从该URL加载相应的类文件。如果它来自 jar 文件,您应该能够从 jar: URL 中提取文件名(或源 URL)。如果您从类路径中手动读取元数据文件,也应该可以获得详细的包信息。

如果未设置系统属性,我很确定如果没有像您已经在做的那样实际创建新工厂,您将无法获得所需的信息。

【讨论】:

以上是关于如何找出正在使用的 JAXP 实现以及它是从哪里加载的?的主要内容,如果未能解决你的问题,请参考以下文章

无监督学习

虚幻4引擎可以建模吗?如果可以建模,如何建?用虚幻4引擎做游戏,模型是从哪里来的?用maya还是3dmax?

Nacos 如何实现服务自动注册

ANTLR - 如何确定哪种解析树“最适合”某些代码

为啥称为“业务逻辑”?这个词是从哪里来的? [关闭]

如何以编程方式找出哪台计算机是 Windows 中的域控制器?