Как мне исправить исключение Java LinkageError?

#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) являются наиболее распространенными среди проблем с загрузчиком классов.