Загрузка классов Tomcat, кажется, не ведет себя так, как описано - PullRequest
2 голосов
/ 07 сентября 2011

Я использую tomcat 6.0.23, и согласно загрузчику классов документация веб-приложения должны искать классы в следующем порядке:

  1. Bootstrap
  2. System
  3. WEB-INF / классы
  4. WEB-INF / Lib
  5. Общее

У меня есть веб-приложение, которое использует hibernate, и jiber-файлы hibernate находятся в каталоге WEB-INF / lib. При самостоятельном запуске все отлично работает.

У меня также есть файл jar, который должен находиться в каталоге tomcat / lib, так как он содержит некоторые классы, которые необходимо загрузить при запуске (фабрика объектов и объекты, которые она создает). Эти классы используют toplink для своей реализации JPA, и вот здесь я получаю проблему.

Мне нужно поместить файлы toplink, где они могут быть доступны при запуске tomcat, поэтому я поместил их в каталог tomcat / lib. В соответствии с порядком загрузки классов, указанным выше, когда веб-приложение, использующее hibernate, хочет иметь классы реализации hibernate, оно должно найти их в своем каталоге WEB-INF / lib, но в действительности происходит поиск классов реализации toplink из tomcat / lib. каталог, и я получаю исключение приведения класса.

Может кто-нибудь объяснить, почему мои загрузчики классов webapp не находят то, что им нужно, в своем каталоге WEB-INF / lib, или предложить способ отладки пути к классам во время выполнения?

Спасибо.

1 Ответ

4 голосов
/ 07 сентября 2011

Обязательно прочитайте и поймите абзац, предшествующий приведенному вами списку:

"Когда обрабатывается запрос на загрузку класса из загрузчика классов WebappX веб-приложения, этот загрузчик классов сначала просматривает локальные репозитории, а не делегирует их перед поиском. Существуют исключения. Классы, являющиеся частью базы JRE классы не могут быть переопределены. Для некоторых классов (таких как компоненты синтаксического анализатора XML в J2SE 1.4+) может использоваться одобренная функция J2SE 1.4. "

С какими этими "классами реализации hibernate" у вас возникают проблемы? (Классы реализации Hibernate будут полностью отличаться от классов Toplink.) Являются ли они классами javax.persistence? Они могут (или не могут) подпадают под категорию «Базовые классы JRE» , которые ведут себя по-разному.

Редактировать: Исходя из вашего комментария, это просто типичная проблема загрузки кросс-загрузчика. Загрузка классов Tomcat работает точно так, как вы ожидаете. Если вы посмотрите на классы JPA, где происходит эта инициализация, вы найдете строку, подобную этой:

Enumeration<URL> resources =
    cl.getResources("META-INF/services/" + PersistenceProvider.class.getName());

Загружает все PersistenceProviders из все ClassLoaders, включая ваш Toplink в каталоге lib. Затем он немедленно делает это:

for ( PersistenceProvider provider : providers ) { ...

Это строка 77 javax.persistence.Persistence, откуда исходит ваше исключение. Это связано с тем, что класс PersistenceProvider, указанный в этой строке, взят из загрузчика классов webapp, но коллекция содержит два экземпляра: реализацию Hibernate из того же загрузчика классов и реализацию Toplink из другого загрузчика классов.

Эта глобальная статическая инициализация - одна из главных вещей, которая помешала мне перейти на JPA. Я до сих пор просто использую Hibernate из-за подобных проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...