2008-11-25 2 views
2

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

Есть два веб-приложения WebApp1 и webapp2, оба такая же система, но в разных версиях.

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

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

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

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

ответ

1

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

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

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

0

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

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

Назовём эту банку 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 (ver 2) вместо ver 1 !!

Надеюсь, это даст вам некоторое преимущество.

+0

Я думаю, что более вероятно, что у вас есть дополнительная версия comutils.jar, развернутая где-то в пути к классам WebApp1, чем то, что Tomcat Classloader внезапно загружает классы извне, это путь к классам ... проверьте, что MailSender.class находится только в одно место. – 2008-11-25 19:21:45

1

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

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

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

1

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

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