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

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

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

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

[P.S. Очень хорошая причина, чтобы начать использовать архитектуру модуля OSGi на мой взгляд!]

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

Ответы [ 5 ]

18 голосов
/ 27 сентября 2008

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

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

5 голосов
/ 03 октября 2008

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

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

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

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

3 голосов
/ 26 сентября 2008

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

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

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

2 голосов
/ 26 сентября 2008

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

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

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

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

0 голосов
/ 26 сентября 2008

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

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

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

...