Был 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.

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

  1. удалите все банки API из вашего приложения и используйте те из JDK. Например, снять банка, содержащая орг.XML.саксофон или орг.консорциума W3C.дом.
  2. включить все библиотеки в вашей войне, которые ссылаются на классы, которые вы хотите ссылаться. Например, включите копию библиотеки 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