Как узнать, какая реализация JAXP используется и откуда она была загружена?

Я хотел бы предоставить диагностическую информацию о том, какая реализация 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?


person Daniel Fortunov    schedule 25.11.2009    source источник


Ответы (5)


Довольно сложно предсказать, какая конкретная реализация фабрики JAXP будет загружена без фактического создания экземпляра, потому что процесс выбора реализации.

Из официальных часто задаваемых вопросов о JAXP (вопрос 14):

Когда приложение хочет создать новый экземпляр JAXP DocumentBuilderFactory, оно вызывает статический метод DocumentBuilderFactory.newInstance(). Это вызывает поиск имени конкретного подкласса DocumentBuilderFactory в следующем порядке:

  1. Значение системного свойства, например javax.xml.parsers.DocumentBuilderFactory, если оно существует и доступно.
  2. Содержимое файла $JAVA_HOME/jre/lib/jaxp.properties, если он существует.
  3. Механизм обнаружения Jar Service Provider, указанный в спецификации 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 и внешних JAR-файлов для Xerces 2.8 и Xalan), работающих вместе:

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
person Daniel Fortunov    schedule 26.11.2009

Просто добавь

-Djaxp.debug=1

на JAVA_OPTS и вы увидите такую ​​информацию.

Подробнее: https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html

person trang    schedule 15.12.2014

это легко, вы просто устанавливаете

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

трек расскажет вам, какой способ использовать jaxp.

person zg_spring    schedule 11.12.2012

Существует еще одно место, которое ищется перед «реализацией резервной платформы по умолчанию», и это каталог java.endorsed.dirs, как описано в Механизм переопределения одобренных стандартов Java

Механизм переопределения утвержденных стандартов предоставляет средства, с помощью которых более поздние версии классов и интерфейсов, которые реализуют одобренные стандарты или автономные технологии, могут быть включены в платформу Java.

person jwd630    schedule 20.04.2012
comment
Который, кстати, устарел с 8u40, вы можете проверить, используется ли он все еще с -XX:+CheckEndorsedAndExtDirs. - person eckes; 31.10.2016

Это зависит, но обычно нет.

DocumentBuilderFactory.newInstance() либо вернет реализацию DocumentBuilderFactory, настроенную в системном свойстве "javax.xml.parsers.DocumentBuilderFactory", либо фабрику JRE по умолчанию, если системное свойство не установлено. Фабрика по умолчанию, скорее всего, жестко закодирована в реализации метода newInstance и недоступна иным образом.

Если системное свойство установлено, вы можете по крайней мере использовать метод getResource в соответствующем загрузчике классов, чтобы получить URL-адрес, из которого загрузчик классов загрузит соответствующий файл класса. Если это из jar-файла, вы сможете извлечь имя файла (или исходный URL-адрес) из jar: URL-адреса. Подробная информация о пакете также должна быть доступна, если вы вручную читаете файлы метаданных из пути к классам.

Если системное свойство не установлено, я почти уверен, что у вас нет способа получить искомую информацию без фактического создания новой фабрики, как вы уже делаете.

person jarnbjo    schedule 25.11.2009