#java #exception #servlets #classloader
#java #исключение #сервлеты #classloader
Вопрос:
Я разрабатываю приложение для WebSphere 6.1, которое использует Java-сервлет. В моем сервлете я определил идентификатор последовательного хранилища, равный 1L. После развертывания и запуска моего приложения я получаю LinkageError следующего типа (из журнала сервера):
[5/9/11 15:14:26:868 EDT] 0000001c WebApp
E [Servlet Error]-[ManageRecordsConsumerServlet]: java.lang.Exception:
java.lang.LinkageError: LinkageError while defining class:
<redacted>.docindexupdate.batch.servlet.ManageRecordsConsumerServlet
Could not be defined due to: (<redacted>/docindexupdate/batch/servlet
/ManageRecordsConsumerServlet) class name must be a string at offset=2074
This is often caused by having a class defined at multiple
locations within the classloader hierarchy. Other potential causes
include compiling against an older or newer version of the class
that has an incompatible method signature.
Я не уверен, в чем проблема. Я видел это ранее, прежде чем определять uid последовательной версии, и решил, что, определив это и будучи последовательным, будущие обновления файла класса будут выполняться успешно. Во время компиляции или развертывания на сервере ошибок нет. Возможно ли, что более старая версия сервлета кэшируется где-то в экземпляре WebSphere (в данный момент я развертываю только на своей машине разработчика)?
The
class name must be a string at offset=2074
строка также сбивает с толку.
Ответ №1:
Я подозреваю, что у вас есть jar, который загружается в двух разных загрузчиках классов. Под этим я подразумеваю, что ваш websphere server при запуске загружает этот jar или имеет подтвержденный каталог с этим jar. Кроме того, ваш EAR, который вы развертываете, имеет этот jar в своей библиотеке. Они могут конфликтовать во время выполнения
Что я бы предложил, так это выяснить, какому jar ManageRecordsConsumerServlet принадлежит, и либо удалить его из вашей библиотеки EAR, либо из библиотеки, одобренной Websphere (лучше всего было бы использовать вашу библиотеку EAR).
Комментарии:
1. Действительно, похоже, что это то, что происходило — война, в которой находится сервлет, была указана как «Требуемый проект на пути сборки». Удаление этой зависимости устранило проблему (а также значительно сократило время сборки.)
2. Хммм … после нормальной работы в течение нескольких дней ошибка необъяснимым образом появилась снова. Если бы мой компьютер не работал так медленно, я мог бы устранить это быстрее.
Ответ №2:
Это может быть управление версиями, но я так не думаю.
Когда два класса загружаются разным classloader, обычно генерируется ClassNotFoundException.
Когда класс передается по проводному каналу / загружается из дискового кэша, обычно генерируется исключение VersionMismatchException.
Когда используется класс с разными сигнатурами методов, генерируется NoSuchMethodError или что-то подобное.
Я думаю, что в этом случае поврежден файл класса. Может быть поврежден в кэше или в JAR.
Комментарии:
1. По моему опыту, ошибка NoSuchMethodError обычно возникает из-за проблем с управлением версиями, и я видел исключение ClassNotFoundException только в webspehre, weblogic и jboss, когда класс НЕ находится в classloader. LinkageError и ClassCastException (или проверки instanceof) являются наиболее распространенными среди проблем с загрузчиком классов.