Проблемы с загрузчиком классов. Как определить, какие версии библиотеки (jar-файлы) загружены

StackOverflow https://stackoverflow.com/questions/139534

  •  02-07-2019
  •  | 
  •  

Вопрос

Я только что решил еще одну проблему: *Я-хотя-я-использовал-эту-версию-библиотеки, но-очевидно-мой-сервер-приложений-уже-загрузил-старую-версию-библиотеки -this-library-*issue (вздох).

Кто-нибудь знает хороший способ проверить (или контролировать), имеет ли ваше приложение доступ ко всем соответствующим jar-файлам или загруженным версиям классов?

Заранее спасибо!

[П.С.Очень хороший повод начать использовать Архитектура модуля OSGi с моей точки зрения!]

Обновлять: Этот статья тоже помогла!Это дало мне представление о том, какие классы загружает загрузчик классов JBoss, записав это в файл журнала.

Это было полезно?

Решение

Если вы используете JBoss, существует MBean (репозиторий загрузчика классов iirc), где вы можете запросить все загрузчики классов, которые загрузили определенный класс.

Если ничего не помогает, всегда есть java -verbose:class, который будет печатать местоположение jar для каждого загружаемого файла класса.

Другие советы

Если у вас есть соответствующая информация о версиях в манифесте jar, существуют методы для получения и проверки версии.Нет необходимости вручную читать манифест.

java.lang.Пакет.getImplementationVersion(), getSpecificationVersion() и isCompatibleWith() звучат так, будто они делают то, что вы ищете.

Вы можете получить пакет с помощью this.getClass().getPackage() среди других способов.

В javadoc для java.lang.Package не указаны конкретные имена атрибутов манифеста для этих атрибутов.Быстрый поиск в Google выдал это на http://java.sun.com/docs/books/tutorial/deployment/jar/packageman.html

В текущей версии Java управление версиями библиотеки — довольно расплывчатый термин, который основан на правильной упаковке JAR с полезным манифестом.Даже в этом случае работающему приложению приходится много работать, чтобы собрать эту информацию полезным способом.Среда выполнения JVm вам ничем не поможет.

Я думаю, что лучше всего обеспечить это во время сборки, используя инструменты управления зависимостями, такие как Ivy или Maven, для получения правильных версий всего.

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

Я не думаю, что есть хороший способ это проверить.И я не уверен, что ты хочешь это сделать.Что вам нужно сделать, так это ознакомиться с архитектурой загрузки классов вашего сервера приложений и понять, как она работает.

Упрощенное объяснение того, как это работает:EJB или веб-приложение сначала будут искать класс или ресурс в библиотеках, объявленных в его собственном модуле (ejb-jar или war).если класс там не найден, загрузчик классов перенаправляет запрос загрузчику родительского класса, который является либо объявленной зависимостью (обычно ejb), либо загрузчиком классов приложения, который отвечает за загрузку библиотек и ресурсов, объявленных в пакете Ear. .Если класс или ресурс по-прежнему не найден, запрос перенаправляется на сервер приложений, который будет искать свой собственный путь к классам.

При этом вы должны помнить, что модуль Java EE (веб-приложение, ejb) всегда будет загружать классы из jar, который находится в ближайшей области видимости.Например, если вы упаковываете log4j v1 в файл war, log4j v2 на уровне уха и помещаете log4j v3 в путь к классам вашего сервера приложений, модуль будет использовать jar в своем собственном модуле.уберите его, и он будет использовать тот, что на уровне уха.уберите это, и он будет использовать тот, который указан в пути к классам сервера приложений.Все становится сложнее, когда у вас есть сложные зависимости между модулями.

Лучше всего разместить глобальные библиотеки приложений на уровне ушей.

Должен быть лучший способ, чем тот, который я делаю, но я склонен делать это очень вручную.

  1. Каждый Jar должен иметь номер версии в имени файла (если он не меняет свое имя).
  2. каждое приложение имеет свой собственный путь к классам.
  3. Должна быть причина начать использовать обновленный Jar (новую версию).Не меняйте просто потому, что это доступно, меняйте, потому что это дает вам необходимую функциональность.
  4. Каждый выпуск должен включать все необходимые Jars.
  5. Я храню класс Version, который знает список необходимых ему Jars (он закодирован в исходном файле) и может быть проверен во время выполнения по списку Jars в пути к классам.

Как я уже сказал, это вручную, но оно работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top