Jboss 5, загрузчик классов и несколько экземпляров классов - PullRequest
3 голосов
/ 12 апреля 2011

У меня была проблема с моим приложением.Чтобы возобновить проблему, мне пришлось перенести приложение с jboss 4 на jboss 5.

Во время развертывания войны у меня была такая ошибка:

java.lang.LinkageError: loader constraint violation: when resolving field "DATETIME"
the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class,
javax/xml/datatype/DatatypeConstants, and the class loader (instance of <bootloader>)
for the field's resolved type, javax/xml/namespace/QName,
have different Class objects for that type

После многих поисков я нашелэта ошибка была здесь, потому что у меня было несколько раз одного и того же класса в разных пакетах.Один раз в пакете зависимостей (из моего pom.xml) и один раз предоставленный jboss.

Итак, чтобы решить эту проблему, я дал область действия «предоставлено» для моей зависимости.

НоЯ не понимаю, почему это решение работает.Я думал, что это работает, чтобы иметь несколько раз один и тот же класс в приложении.Я знаю, что это не очень хорошая вещь, но с jboss 4 это работает.

Кто-то может объяснить мне, почему он работает с jboss 4, а не с jboss 5.

Спасибо за ваше объяснение :)

Ответы [ 3 ]

8 голосов
/ 12 апреля 2011

Вы видите, что сервер приложений загружает библиотеки JBoss и библиотеки EAR в отдельные загрузчики классов

Вы можете представить себе иерархию загрузчика классов EAR, похожую (но не обязательно) на:

Bootstrap ClassLoader -> Загрузчик класса системы -> Загрузчик класса системы JBoss -> Загрузчик класса уха -> Загрузчик класса войны.

Где родительский класс загрузчика класса войны - это загрузчик класса уха и т. Д.

Теперь, если в Bootstrap ClasssLoader загружен jar A, а ухо также используется с jar A, у Bootstrap Class Lodaer и Ear Class Loader будет один и тот же класс, созданный дважды в отдельных загрузчиках классов.

Я бы предположил (не уверен на 100%), что JBoss 4 не поставлялся в комплекте с javax / xml / namespace / QName.Если это так, то JBoss 5 более вероятно является другой, обновленной версией Java (4 -> 5 или 5 -> 6).В результате (с новым JBoss 5), когда вы пытаетесь передать javax / xml / namespace / QName в один из ваших классов, он ожидает, что класс будет слышен.Однако вы предоставляете ему класс QName из загрузчика классов Bootstrap из-за предпочтений загрузчика классов (сначала родительский и т. Д.).

Поскольку типы классов равны, но экземпляры классов не равны, вы получаете LinkageError

Редактировать:

Просто два адреса двух комментариев -

Поведение загрузки класса, как отметил jtahlborn, определенно отличается.В обычных приложениях системные классы, такие как QName, будут последовательно искать в загрузчике классов начальной загрузки.В вашей ошибке это выглядит так, как будто javax / xml / datatype / DatatypeConstants загружается в org / jboss / classloader / spi / base / BaseClassLoader.Предположим, что это загрузчик классов EAR (или WAR).Быстрый Google показывает, что является частью семейства xml-apis и, возможно, jaxp-api.

Таким образом, где-то в вашем коде (или другом коде библиотеки, расположенном в загрузчике классов EAR) требовались DatatypeConstants - что заставило поиск класса в загрузчике классов EAR.Создание объекта QName, хотя и загружало класс из загрузчика классов начальной загрузки (вместо EAR).Это может произойти, если класс QName уже был инициализирован системой, что, вероятно, имеет.

Как вы можете себе представить, этого не произойдет.Похоже, у вас последний родитель.Потому что при загрузке класса из механизма загрузки классов JBoss, если бы был включен родительский элемент, начальные DatatypeConstants возвращали бы родительские (bootstrap) DatatypeConstants, а не дочерние элементы.Поэтому, как отметил jtahlborn, вы бы хотели, чтобы детский загрузчик классов здесь игнорировался.

Что касается разрешения, то если вам не нужны зависимости по определенной причине (например, более новая версия лучше текущей), то яделегировал бы реализацию jboss.Если это не так, вы можете взглянуть на элемент class-loading java2ClassLoadingCompliance, который есть в конфигурации jboss.

1 голос
/ 11 августа 2012

-verbose:class в аргументах VM даст информацию о том, как загружается класс. Если есть дубликаты, вы можете удалить конфликтующие банки / банки.

0 голосов
/ 16 марта 2014

Спасибо за объяснение - это было очень полезно.

Я узнал, что эта проблема связана с ошибкой JBoss, которая была исправлена ​​в версии 5.0.0.Но, хотя я использую старую версию JBoss, я все равно получил эту ошибку.Во всяком случае, я несколько раз проводил обширные исследования и запускал дерево зависимостей maven, чтобы увидеть, откуда берутся дубликаты определений.Наконец-то я смог устранить эту ошибку, добавив две зависимости - с установленной областью действия - в мой основной компонент:
(sun.jaxb-impl 2.1, javax.jaxb-api 2.2) Надеюсь, эта информация кому-нибудь поможет.

...