БЫЛИ 6.1 java.lang. VerifyError: ограничение загрузки класса нарушено

Среда, БЫЛ 6.1 на Linux, развертывая веб-приложение, которое использует классы от xercesImpl.jar.

Из-за ограничений политики компании, приложение должно быть развернуто с настройками:

Class Loader Order
    Classes loaded with parent class loader first
->  Classes loaded with application class loader first

WAR class loader policy
    Class loader for each WAR file in application
->  Single class loader for application

ВОЕННЫЙ файл содержит копию xercesImpl.jar, тот же, который был в пути к классу, когда приложение было скомпилировано.

При запуске веб-приложения, когда Spring пытается проанализировать свои конфигурации, он бросает:

java.lang.VerifyError: class loading constraint violated 
    (class: org/apache/xerces/jaxp/DocumentBuilderImpl 
    method: parse(Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;)

АНАЛИЗ ДО СИХ ПОР

Кажется, что это БЫЛО, обеспечивает реализацию org.apache.xerces.jaxp. DocumentBuilderImpl, потому что мы можем удалить xercesImpl.jar из ВОЕННОГО файла и все еще получить ту же ошибку (не ClassNotFoundException). Таким образом БЫЛ, кажется, разрешает ссылки с помощью его собственной копии, которая является несовместимой со ссылками в наших компилируемых файлах класса. Однако единственный другой экземпляр 'xercesImpl.jar', который я могу найти (кроме копии, развернутой с нашим приложением), находится в каталоге deploytool, который, кажется, вне сервера приложений.

Я просканировал все банки в, БЫЛ (весь 1300 их) с

for i in `find . -name \*.jar`; do jar tvf $i|grep -qi xerces && echo $i ; done

и найденный этим ./java/jre/lib/xml.jar содержит все классы в org.apache.xerces.*, таким образом, это вероятно, где classloader разрешает ссылку.

ВОТ СТРАННАЯ ЧАСТЬ:

Если мы изменяемся на "загрузчик родительского класса сначала", мы не видим исключение. Это идет в противоречии с ожидаемым поведением. Мы ожидали бы, что с "приложением classloader сначала" это будет использовать xercesImpl.jar, что мы, если, и используют версию WAS, только если мы устанавливаем "родителя classloader сначала". Это, кажется, назад от того, что мы на самом деле видим.

ВОПРОС:

Как classloader делегация устанавливает взаимодействие с вышеупомянутой информацией для приведения к наблюдаемому поведению?

10
задан Brett Kail 21 December 2011 в 20:19
поделиться

2 ответа

Ваша WAR также включает классы org.xml.sax или org.w3c.dom, а затем вы ссылаетесь на класс за пределами вашего приложения, который также ссылается на эти классы. Это создает сценарий, в котором загрузчик классов вашего приложения видит два экземпляра одного и того же класса, что является ошибкой связывания.

Например, если ваше приложение использует javax.xml.bind.Unmarshaller.unmarshal (InputSource), то Unmarshaller будет загружен из JDK, а класс Unmarshaller будет виден только для JDK InputSource. Когда ваше приложение создает свой InputSource, оно загружает класс из WAR (потому что политика «сначала приложение»), а затем ваше приложение пытается передать экземпляр WAR InputSource в JDK Unmarshaller, который может принимать только экземпляр JDK InputSource.

Есть два решения:

  1. Удалите все jar-файлы API из вашего приложения и используйте те, что из JDK. Например, удалите банку, содержащую org.xml.sax или org.w3c.dom.
  2. Включите в свою WAR все библиотеки, которые ссылаются на классы, на которые вы хотите ссылаться. Например, включите копию библиотеки JAXB в свою WAR.

По моему опыту, ошибки связывания довольно сложно отследить, потому что JVM дают скучную информацию о том, что вызывает добавление ссылок.Обычно я включаю трассировку загрузчика классов, воспроизводю проблему, а затем иду назад, пока не найду класс, загруженный извне приложения, который "звучит так", как будто он может ссылаться на класс, который, как известно, существует внутри приложения.

14
ответ дан 4 December 2019 в 00:59
поделиться

Если мы изменим на «загрузчик родительского класса во-первых, мы не видим исключения. Это противоречит ожидаемому поведение.

Да, верно, это единственный способ увидеть такое поведение. Я могу посоветовать вам взглянуть на "Вы действительно получаете загрузчики классов?" говорить, так как на ваш вопрос нет однозначного или короткого ответа.

http://www.slideshare.net/guestd56374/do-you-really-get-class-loaders http://www.parleys.com/#sl=2&st=5&id=1585

-2
ответ дан 4 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: