Проблемы в ClassLoaders для длительного запуска процесса Tomcat - PullRequest
2 голосов
/ 25 ноября 2008

Мы разместили наши веб-приложения на Tomcat 6.0.18 и столкнулись со следующей проблемой:

Существует два веб-приложения WebApp1 и WebApp2, оба являются одной и той же системой, но разных версий.

Теперь проблема в том, что когда кот работал в течение недели или дольше, то иногда система выдает NoClassDefFoundError! Также у нас возникла странная проблема, когда загрузчик классов WebApp1 загрузил класс, присутствующий в банке WebApp2! Тот же самый jar также присутствует в WebApp1, но версии разные.

Когда мы перезапустили Tomcat, все стало работать нормально! Наш JRE 1.5.10

Пожалуйста, дайте мне знать, если вы столкнулись с такими проблемами.

С уважением, Jatan Porecha

Ответы [ 4 ]

1 голос
/ 25 ноября 2008

Есть ли особая причина, по которой вы размещаете 2 версии одного и того же кода на одном сервере?

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

1 голос
/ 25 ноября 2008

Мне все еще не хватает представителя, чтобы добавить комментарий, поэтому мне придется опубликовать другой ответ. :)

Похоже, что MailSender.class загружается в Tomcat, а не в каждое отдельное веб-приложение. Сначала WebApp2 загружает его, и он работает, даже если он загружен во все Tomcat, не являющиеся частными для WebApp2. Когда WebApp1 нужен класс, он уже видит его загруженным в родительский Tomcat и не пытается загрузить один закрытый в WebApp1.

Сначала я бы предложил вам проверить каталоги Tomcat, JRE и т. Д., Чтобы выяснить, есть ли в этих путях копия jar или класса. После этого я вручную удалил класс из каждого из двух jar-файлов и перезапустил Tomcat или веб-приложения, чтобы посмотреть, что произойдет - вы ожидаете, что он завершится неудачно и произведет трассировку стека, и это скажет вам, где ваш класс загружается впервые. и кто пытается загрузить его. (Например, из имени класса, возможно, у вас есть почтовый API, загруженный в JVM Tomcat, который загружает класс - в Tomcat, а не в ваше веб-приложение).

1 голос
/ 25 ноября 2008

Я столкнулся со многими, множеством разновидностей странностей загрузчика классов с Tomcat - даже если вы сами не выполняете код загрузчика классов, сам Tomcat легко создает проблемы. Наиболее распространенной проблемой, по-видимому, является повторная выгрузка и перезагрузка веб-приложения, что приводит к утечке загрузчиков классов и, в конечном итоге, к запуску Tomcat из памяти.

Самая распространенная причина, по которой я видел несоответствия версий, заключается в том, что Tomcat следит за тем, чтобы некоторые классы и jar-файлы (часть самого Tomcat) опережали любые другие в вашем пути к классам в веб-приложении. Наиболее распространенным примером, по-видимому, является использование обыкновенной регистрации и загрузчики классов могут быть загружены, выгружены или храниться, когда вы этого не ожидаете.

Можете ли вы предоставить еще несколько деталей - если баночка от стороннего производителя, есть большая вероятность, что кто-то уже видел проблему раньше. Если это ваш собственный jar, то есть ли у вас какой-либо собственный код загрузчика классов в приложении?

0 голосов
/ 25 ноября 2008

Спасибо Крису за ваш ответ.

Jar является частью системы и имеет некоторые общие классы, которые используются другими процессами.

Давайте назовем этот jar comutils.jar. Итак, сценарий похож на

WebApp1 (ver 1)
  |
  |- comutils.jar (ver 1)
        |
        |- MailSender.class (ver 1)


WebApp2 (ver 2)
  |
  |- comutils.jar (ver 2)
        |
        |- MailSender.class (ver 2)

Этот класс MailSender является синглтоном.

Теперь иногда случается так, что всякий раз, когда код WebApp1 вызывает любой метод MailSender после извлечения его экземпляра с использованием метода getInstance, тогда фактический вызов переходит к MailSender (версия 2) вместо версии 1 !!

Надеюсь, это поможет вам.

...