Почему загрузчик классов TomEE не находит Hibernate-классы из ear/lib?
Я строю приложение классического уха, содержащее субмодуль EJB (в банку) и WEB (в войну).
Я развернул свое ухо (JAR + WAR) в TomEE и использовал провайдера Hibernate JPA. Я получаю следующую ошибку:
Caused by: java.lang.NoClassDefFoundError: org/hibernate/integrator/spi/Integrator
Банки в спячке находятся в ear/lib
, Существует hibernate-core-4.2.16.Final, который содержит класс org/hibernate/integrator/spi/Integrator
,
Так что я думаю, что процесс Tomee ClassLoader не загружает класс из моей папки ear / lib.
Это правильно? Если это так, почему?
Помогите, пожалуйста
1 ответ
Он не обнаруживает его оттуда, так как не предполагается, что такие "глобальные" библиотеки должны быть размещены по умолчанию. Справочная документация TomEE гласит:
Минимум три загрузчика классов: загрузчик классов для уха, один для каждого ejb-jar и один для каждого WAR-файла.
Как мы узнали из этой цитаты, приложение EAR, особенно его модули EAR, инициализируются со своим собственным экземпляром загрузчика классов очень рано при запуске контейнера, и до того, как инициализация WAR вступает в действие с собственным загрузчиком классов.
Я предполагаю, что ваш EAR-модуль (тот, который находится внутри jar-файла) представляет собой модуль внутреннего уровня, сканирующий Hibernate, пытающийся загрузить файлы соответствующих классов. К сожалению, он не может "видеть" их в рамках своего загрузчика классов.
Решение
Однако это сработает, когда вы поместите все jiber Hibernate (и все переходные зависимости, такие как antlr, dom4j, javassist,...) в глобальный lib
каталог в соответствии с макетом каталога TomEE. В любом случае это имеет гораздо больший смысл, поскольку, таким образом, оно может быть повторно использовано различными частями вашего приложения, которые могут / будут включены в развертываемый EAR, или даже совершенно разные приложения, запущенные в одном контейнере. Таким образом, глобальные файлы JAR будут доступны в classpath модуля ejb, и, таким образом, Hibernate может быть запущен при запуске контейнера.
Поместив его в установку всего контейнера, вы можете затем удалить баночки Hibernate из EAR/lib
папка (объявив его как предоставленную зависимость в pom.xml
в настройках проекта Maven).
Это - как побочный эффект также значительно уменьшит размер вашего EAR-пакета, поскольку библиотеки теперь "глобальные". Во время выполнения вы также заметите, что объем памяти сокращается, поскольку все файлы классов Hibernate ORM будут загружаться в контейнер только один раз, а не несколько раз для разных EAR-пакетов или WAR-пакетов.
Подсказка (ы):
При работе с TomEE-7 я рекомендую обновить Hibernate как минимум до версии 4.3.11, поскольку в версии 4.3.x поддержка Hibernate JPA доступна для версии 2.1 спецификации. Более того, если вы можете это сделать, попробуйте перенести ваше приложение на версию Hibernate 5.2.x, поскольку это принесет множество улучшений.
Для получения полного списка переходных зависимостей Hibernate, проверьте список для версии 4.2.x здесь или для версии 4.3.x здесь, Hibernate 5.2.x аналогично. Вам нужно только собрать / связать упомянутые "Зависимости компиляции" и поместить их в глобальный каталог "lib" TomEE, чтобы все заработало.
Также поместите драйвер JDBC, который вы используете в своем приложении, в глобальный
lib
папка.
Надеюсь, поможет.