当前位置: 首页 > 面试题库 >

如何找出正在使用的JAXP实现以及从何处加载?

许安邦
2023-03-14
问题内容

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


问题答案:

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

从官方JAXP常见问题解答(问题14)中:

当应用程序想要创建一个新的JAXP DocumentBuilderFactory 实例时,它将调用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工厂都可以指定一个独立的实现。通常使用一个解析器实现和另一个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


 类似资料:
  • py.test在哪里以及如何寻找固定装置?我在同一个文件夹的两个文件中有相同的代码。当我删除conftest.py时,无法找到正在运行test_conf.py(也在同一文件夹中。为什么sonoftest.py没有被搜查? 医生说 http://pytest.org/latest/fixture.html#fixture-作用 pytest查找test_ehlo因为test_前缀。测试函数需要一个名

  • 问题内容: 我需要将JNDI名称添加到hibernate中的活动连接池的代码。我已经在Jboss服务器中将连接池配置为JNDI名称为“ EmployeeDB” 如何在hibernate.cfg.xml中配置它? 如果我使用的是Hibernate 4 Final版本,请给我hibernate.cfg.xml的代码。 问题答案: 在Jboss服务器中配置的数据源JDNI名称由属性指定。 基本应如下所示

  • 目前我正在使用JDK1.8。需要知道什么是jaxp版本。为了避免声纳违规,请尝试设置以下属性,结果是“org.xml.sax.saxNotRecognitizedException:Property”http://javax.xml.XMLConstants/property/accessExternalDTD“不被承认。“SchemaFactory SchemaFactory=SchemaFac

  • 我使用的是slf4j,它是日志记录,但它并没有像预期的那样使用logback(因为logback(-test)中发生了变化)。xml不会影响日志记录行为。 此外,我删除了对任何日志库的所有间接引用(常见 谢啦!

  • 问题内容: 我们已经发布了几年前基于JDK 5开发的分布式Web应用程序。 JMX将如何帮助该应用程序? 1)它可以帮助我监视性能(内存,CPU,网络和磁盘IO)吗? 2)如果是这样,则应用程序部署在多台服务器中,如何在一个仪表板中进行监视? 3)是否必须对现有应用程序进行任何新的代码更改,或者可以在不更改代码的情况下进行监视? 4)除了性能监控,我们还能做什么?由于名称是Management E

  • 问题内容: 有谁知道如何以编程方式找出java类加载器实际从何处加载类? 我经常在大型项目中使用类路径,并且手动搜索并不是一个好的选择。我最近遇到了一个问题,其中类加载器正在加载不正确的类版本,因为它位于两个不同位置的类路径上。 那么,如何让类加载器告诉我实际的类文件来自磁盘上的什么地方呢? 编辑:如果类加载器由于版本不匹配(或其他原因)而实际上无法加载该类,该怎么办,在读取它之前我们是否能找出它