Был 6.1 java.ленг.VerifyError: нарушено ограничение загрузки класса
среда была 6.1 в Linux, развертывая webapp, который использует классы от xercesImpl.сосуд.
из-за ограничений политики компании, приложение должно быть развернуто настройки:
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.Джар, тот самый, что был в classpath при компиляции.
при запуске webapp, когда Spring пытается проанализировать его конфигурации, он броски:
java.lang.VerifyError: class loading constraint violated
(class: org/apache/xerces/jaxp/DocumentBuilderImpl
method: parse(Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;)
АНАЛИЗ
это представляется, что обеспечивает реализацию
орг.апаш.xerces.как jaxp.DocumentBuilderImpl, потому что мы можем удалить
xercesImpl.jar из файла WAR и по-прежнему получает ту же ошибку (не
ClassNotFoundException). Таким образом, представляется решении ссылок
использование собственной копии, несовместимой со ссылками в нашей
скомпилированные файлы классов. Однако, единственный экземпляр 'xercesImpl.банк'
Я могу найти (кроме копии, развернутой с нашим приложением) в каталоге
deploytool
, который, кажется, вне сервера приложений.
Я просмотрел все банки в WAS (все 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 разрешает ссылку.
ВОТ СТРАННАЯ ЧАСТЬ:
если мы изменим на "загрузчик родительского класса первым", мы не увидим исключения. Это противоречит ожидаемому поведению. Мы ожидаем, что с "application classloader first" он будет использовать в xercesImpl.jar, который мы при условии, и использовать версию WAS, только если мы установили " Родительский classloader сначала." Это кажется обратным тому, что мы видим на самом деле.
ВОПРОС:
как параметр делегирования classloader взаимодействует с вышеуказанной информацией, чтобы привести к наблюдаемому поведению?
5 ответов
ваша война также включает в себя любую организацию.XML.саксофон или орг.w3c.классы dom, а затем вы ссылаетесь на класс, который находится вне вашего приложения, который также ссылается на эти классы. Это создает сценарий, в котором загрузчик классов приложений имеет видимость двух экземпляров одного класса, что является ошибкой связи.
например, если ваше приложение использует javax.XML.связывать.Он вызывается.unmarshal(InputSource), затем Unmarshaller будет загружен из JDK, а Unmarshaller класс имеет видимость только для JDK InputSource. Когда ваше приложение создает свой InputSource, оно загружает класс из WAR (потому что политика "app first"), а затем ваше приложение попытается передать экземпляр WAR InputSource в JDK Unmarshaller, который может принимать только экземпляр JDK InputSource.
есть два решения:
- удалите все банки API из вашего приложения и используйте те из JDK. Например, снять банка, содержащая орг.XML.саксофон или орг.консорциума W3C.дом.
- включить все библиотеки в вашей войне, которые ссылаются на классы, которые вы хотите ссылаться. Например, включите копию библиотеки JAXB в свою войну.
по моему опыту, ошибки связи довольно трудно отслеживать, потому что JVMs дают паршивую информацию о том, что вызывает добавление связей. Я обычно включения загрузчик Class трассировки, воспроизведите проблему, а затем пятиться, пока я не найду класс загружен из вне приложения, которое "звучит как", оно может ссылаться на класс, который, как известно, существует внутри приложения.
наша проблема развертывалась на 8.5.
в нашем веб-приложении у нас есть клиент веб-службы, созданный cxf. Никакой вопрос.
когда мы добавили в TIKA-parser для обнаружения типа mime, то мы получили эту проблему.
мы исключили три зависимости:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>${apache.tika.version}</version>
<exclusions>
<exclusion>
<artifactId>geronimo-stax-api_1.0_spec</artifactId>
<groupId>org.apache.geronimo.specs</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
<exclusion>
<artifactId>xmlbeans</artifactId>
<groupId>org.apache.xmlbeans</groupId>
</exclusion>
</exclusions>
</dependency>
Как только они были исключены, наше приложение началось успешно.
может быть, это слишком поздно, но мы решили эту проблему, удалив эту строку на сервер.XML-код:
jaxb-2.1
отключить проверку байт-кода
java.ленг.Исключение verifyerror - Runtime Непроверенное Исключение после загрузки файла класса в Websphere JVM следующим процессом будет изменение байтового кода.во время проверки байтового кода ,если наш класс нарушает ограничения JVM, появляется эта ошибка.
отключение проверки байт-кода. Перейти к
консоль администрирования->
server1->
java и управление процессами->process definition->
аргументы JVM`
и в аргументах JVM передайте следующую строку
-Xverify:none
и в рабочей области откройте xml-файл ApplicationDeploymentDescriptor, перейдите на вкладку развертывание, выберите PARENT_LAST для war, а также для первого варианта. это останавливает ошибки проверки xml.
если мы изменим на " загрузчик родительского класса сначала" мы не видим исключения. Это идет вразрез с ожидаемым поведение.
Да, это правильно, это единственный способ увидеть такое поведение. Я могу предложить вам взглянуть на "вы действительно получаете загрузчики класса?- говори, потому что на твой вопрос нет единого или краткого ответа . вопрос.
http://www.slideshare.net/guestd56374/do-you-really-get-class-loaders http://www.parleys.com/#sl=2&st=5&id=1585