решение для java.lang.VerifyError в tomcat 7.0.23/jdk 1.6.x?

Когда я развернул встроенное веб-приложение maven 3.0.3 в tomcat 7.0.23 в Linux (java 1.6.x) и получил доступ к опубликованным моим учетным данным на странице входа, я получил следующую ошибку. pom.xml ссылается на сервлет 2.5, jsp 2.1 и JSTL 1.2.

Почему я получаю эту ошибку? что я могу сделать, чтобы избежать этого?

У меня есть другие файлы .war, развернутые на том же экземпляре tomcat, и я никогда не сталкивался с этой проблемой в этих приложениях.

1-й JSP (login.jsp), который я выполнил http GET, не выдал ошибку. При выполнении POST из 1-го JSP во 2-й Jsp (ChLogin.jsp) возникла проблема.

===========================

основная причина

java.lang.VerifyError: (class: org/apache/jsp/ChLogin_jsp, method: _jspService signature: (Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V) Inconsistent stack height 0 != 1
    java.lang.Class.getDeclaredConstructors0(Native Method)
    java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    java.lang.Class.getConstructor0(Class.java:2699)
    java.lang.Class.newInstance0(Class.java:326)
    java.lang.Class.newInstance(Class.java:308)
    org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:172)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

ОБНОВЛЕНИЕ 1
WEB-INF\lib веб-приложения НЕ содержит jar-файлы сервлета, jsp или JSTL. Он содержит много зависимостей приложений и пружинных банок (мы используем Spring MVC).

ОБНОВЛЕНИЕ 2
Мы не выполняем предварительную компиляцию JSP. Однако это цель на другой день.

ОБНОВЛЕНИЕ 3
Обнаружено, что этой проблемы не было в tomcat 7.0.12, 7.0.14, 7.0.16, но началось с 7.0.19. Опубликовано в списке рассылки пользователей tomcat. получил ответ, что, возможно, виноват компилятор eclipse JDT. Подтверждено, что это действительно так, заменив компилятор в tomcat 7.0.23/27 компилятором JDT tomcat 7.0.16 и LO & BEHOLD, все в порядке. Я планирую написать команде компилятора Eclipse JDT (если она есть) и опубликовать сообщение об этой ошибке.


person anjanb    schedule 30.03.2012    source источник
comment
Используете ли вы переписывание байт-кода, фреймворки аспектов или java-агенты, которые могут обрабатывать скомпилированные jsps?   -  person Jörn Horstmann    schedule 30.03.2012
comment
Мы используем библиотеку Spring MVC, но эти JSP не настроены для Spring. Spring настроен на использование другого URL-адреса.   -  person anjanb    schedule 30.03.2012
comment
У меня есть тот же файл .WAR для Tomcat 5.5, и он отлично работает. Итак, что мне не хватает?   -  person anjanb    schedule 02.04.2012
comment
Я получаю тот же VerifyError после изменения библиотеки pom.xml для JSTL для использования предоставленной области. Что еще мне делать? Спасибо.   -  person anjanb    schedule 26.04.2012
comment
На всякий случай файл WAR не содержит jar-файлов сервлетов/JSP/JSTL. Кроме того, я не компилирую файлы jsp. Сервер приложений должен скомпилировать файлы JSP.   -  person anjanb    schedule 26.04.2012
comment
Выложите пожалуйста небольшой WAR файл с такой же бедой. Это поможет исследовать/воспроизвести проблемы.   -  person Yves Martin    schedule 26.04.2012
comment
Ваша проблема сложная. У нас должен быть способ легко воспроизвести его, если вы хотите получить соответствующий ответ. Пожалуйста, опубликуйте небольшой WAR или SSCCE для сборки из исходного кода.   -  person Yves Martin    schedule 02.05.2012
comment
Хотел бы я опубликовать небольшой WAR с той же проблемой. Я попытаюсь, хотя.   -  person anjanb    schedule 03.05.2012
comment
По крайней мере, пожалуйста, опубликуйте подробный вывод: class, одной трассировки стека недостаточно. Кстати, вам придется приложить усилия, чтобы воспроизвести проблему с небольшим набором кода (даже самым маленьким набором, насколько это возможно), даже среда может не ответить из-за столь ограниченной информации.   -  person Yves Martin    schedule 29.05.2012
comment
Есть ли шанс, что вы могли бы опубликовать полный исходный код JSP?   -  person Christopher Schultz    schedule 30.05.2012
comment
Или сгенерированный исходный файл Servlet Java из рабочего каталога Tomcat?   -  person Yves Martin    schedule 30.05.2012
comment
к сожалению, собственный код компании - я не смогу его опубликовать.   -  person anjanb    schedule 31.05.2012
comment
как я мог опубликовать подробный вывод: class ?   -  person anjanb    schedule 31.05.2012


Ответы (6)


Ошибка вполне очевидна: в яшме есть баг, создающий байт-код. Сгенерированный код не очищает кадр стека Inconsistent stack height 0 != 1

Вы можете попробовать перетасовать код, разбить его на методы, переместить строки туда-сюда, и ошибка может исчезнуть. Также можете ли вы опубликовать соответствующую информацию о сервлете jsp (соответствующем *.jsp) из web.xml (обычно где-то в conf), чтобы проверить параметры компилятора?

person bestsss    schedule 27.05.2012
comment
Благодарю. Я использую стоковую версию tomcat 7.0.27 (apache-*.tar.gz) и ничего не менял в файле web.xml. Другие веб-приложения, развернутые на том же коте, не имеют проблем. Почему только мое веб-приложение? - person anjanb; 28.05.2012
comment
Почему только мое веб-приложение, прочитайте ответ еще раз, возможно, это (редкая) ошибка. Я понятия не имею, как на самом деле выглядит web.xml на стандартном tomcat, и обычно настройка jasper в любом случае является хорошей идеей. Попробуйте некоторые из вариантов в ответе, т.е. методы извлечения добавляют некоторую локальную переменную и т. д., и, скорее всего, проблема исчезнет. Вашему веб-приложению просто не повезло. - person bestsss; 28.05.2012
comment
Сам Jasper не генерирует байт-код. Он генерирует исходные файлы Java как стандартный сервлет, скомпилированный с помощью компилятора Eclipse JDT (который можно считать надежным). - person Yves Martin; 29.05.2012
comment
@YvesMartin, я знаю, что когда-то я даже написал собственный обработчик для использования либо внутреннего компилятора JBuilder, либо Sun javac V8. Сервлет JSP обрабатывает все *.jsp (по умолчанию) и выполняет свои функции (можно было даже обмануть jasper и использовать его локальные переменные). Мне было любопытно, использует ли он JDT (и он доступен в пути к классам) или разветвляет javac. Даже JDT надежен. Я столкнулся с ошибками, VerifyError определенно является ошибкой (плохой байт-код) в теле метода, иначе (например, разные версии класса) будет какая-то другая LinkageError, такая как NoSuchMethodError, ClassFormatError или что-то в этом роде. - person bestsss; 29.05.2012
comment
Уже получил VerifyError с JSP API в WAR, и я не одинок: stackoverflow.com/questions/8821088/ - person Yves Martin; 30.05.2012
comment
Еще один: stackoverflow .com/questions/7533878/ - person Yves Martin; 30.05.2012
comment
@YvesMartin, обратите внимание, что VerifyError не для скомпилированного сервлета (org/apache/jsp/ ChLogin_jsp), а для class: org/apache/jasper/runtime/JspApplicationContextImpl и class: org/apache/jasper/compiler/JspUtil; дело совсем в другом. Я бы попросил OP просто вызвать [через веб-браузер] остальные JSP и посмотреть, не появится ли какая-либо другая VerifyError. - person bestsss; 30.05.2012
comment
спасибо за вклад. Я обнаружил, что действительно виноват встроенный компилятор eclipse JDT, который генерирует код для JSP. Подробнее в обновлении 3 - person anjanb; 31.05.2012
comment
@anjanb, это не первая ошибка в JDT eclipse [у нас было несколько проблем, отправленных в течение многих лет - избр. предупреждение для double==double - сравнение равного бла, бла - подсказка не работает для NaN], если вы можете отправить JSP (сгенерированный java), я мог бы даже попробовать решить проблему, что касается немедленного решения, вы можете переключиться на компилятор javac в web.xml. Ищите документ jsp servelt для получения дополнительной информации (он нужен вам в вашем веб-приложении) - person bestsss; 31.05.2012
comment
@bestsss: спасибо. Либо используйте javac, либо предварительно скомпилируйте классы. Кажется, самый простой вариант - использовать javac. - person anjanb; 04.06.2012

Эта ошибка означает, что JSP был скомпилирован для конкретной реализации Servlet/JSP/JSTL, но затем Tomcat пытается загрузить скомпилированные классы с другой реализацией/версией, доступной в ClassPath.

Вероятно, это происходит потому, что ваш WAR содержит файлы jar с сервлетом, jsp и/или jstl API и/или реализацией. Поскольку используемые версии соответствуют реализации Tomcat 5.5, она работает там, но не работает с более поздними реализациями.

Вы должны установить для область значение provided для таких зависимостей в вашем Maven POM, чтобы исключить эти банки из WAR WEB-INF/lib.

Чтобы убедиться, что скомпилированный на лету код не загружает альтернативные зависимости, вы должны запустить Tomcat с -verbose:class. Последние строки перед ошибкой могут помочь догадаться, что не так.

Обновление от 30 мая 2012 г. Есть ли у вас jasper, javax.el или el-api банка в WEB-INF/lib? Если это так, удалите его / их.

Также возможно, что taglib, который вы использовали, специально скомпилирован для Tomcat 5.5 Servlet 2.3 API и ломается, когда Tomcat 7.

person Yves Martin    schedule 02.04.2012
comment
Спасибо. Вы должны установить область действия для таких зависимостей в вашем Maven POM. Можете ли вы уточнить немного больше? указать мне какой-нибудь образец? - person anjanb; 03.04.2012
comment
Я связываю область со ссылкой на Maven о области зависимости. Я сделал ошибку - вы должны использовать предоставленный в вашем случае. - person Yves Martin; 03.04.2012
comment
Как бы то ни было, я действительно думаю, что у @Yves есть правильный ответ. Убедитесь, что все ваши записи <dependency> для сервлета, jsp и jstl содержат <scope>provided</scope> внутри них. Попробуйте и хотя бы дайте нам знать, если это сработало. - person sparc_spread; 08.04.2012
comment
Каково содержание вашего WEB-INF/lib? Вы предварительно скомпилировали свой JSP с помощью Jasper jspc? - person Yves Martin; 26.04.2012
comment
У меня есть куча банок, связанных с приложениями, и куча банок, связанных с пружинами. не содержит сервлет, jsp или jstl. Нет, я не компилирую JSP. - person anjanb; 27.04.2012
comment
Как насчет XML-вещей, таких как STAX, Xerces, Xalan..., которые теперь включены в JDK? - person Yves Martin; 27.04.2012
comment
Весь список банок генерируется/получается maven. Нет, ничего из вышеперечисленного. - person anjanb; 27.04.2012
comment
это проприетарный код. не может публиковать код. не имеют разрешения. - person anjanb; 03.05.2012
comment
Поэтому, пожалуйста, создайте небольшой SSCE с нуля с большинством используемых библиотек. Он не работает с одним JSP, его нетрудно воспроизвести. - person Yves Martin; 03.05.2012
comment
Модифицировал этот ответ: VerifyError не имеет ничего общего с неправильными версиями JSP и/или предварительной компиляцией. VerifyError — это ошибка JVM, жалующаяся на то, что сам файл .class (точнее, байт-код) неисправен. - person Christopher Schultz; 30.05.2012
comment
Я все еще жду какой-либо дополнительной информации (подробный: класс) или даже самого байт-кода, почему бы и нет - есть инструменты для чтения и проверки его структуры. Сгенерированный JSP исходный код сервлета должен быть доступен во временном каталоге. Можем ли мы получить его? - person Yves Martin; 30.05.2012

Пробовали ли вы отключить Split Verifier: -XX:-UseSplitVerifier

Вот ссылка на параметры JVM: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

Я видел нечто подобное с Java 7 и VerifyError.

person AWhitford    schedule 26.04.2012
comment
@anjanb Нет, этот флаг отключает верификатор, используемый по умолчанию в последних JDK, и возвращается к более старой версии. Я ожидаю, что это поможет только в том случае, если ваша цепочка инструментов выполняет переплетение байт-кода где-то вдоль линии. - person rxg; 02.05.2012
comment
на данный момент JSP, в который мы отправляем http-данные, не является spring jsp, и мы на самом деле не используем какой-либо байт-код, вплетающий какой-либо наш код; тем не менее, попробуем и сообщим вам в ближайшее время. - person anjanb; 03.05.2012

Попробуйте распечатать путь к классам (System.out.println("java.class.path");) Сравните путь к классам tomcat5 и tomcat7. Проверьте, в чем разница в пути к классам.

person Snake Eye    schedule 02.05.2012
comment
в старом пути к классам требовалось намного больше банок. Я пытаюсь уменьшить количество банок здесь. - person anjanb; 28.05.2012
comment
Да, таким образом вы можете понять, что происходит не так... убедитесь, что путь к классам такой же... - person Snake Eye; 04.06.2012

Это произошло со мной на Tomcat 6.0.35 и только на одной странице jsp, на которой есть только:

<jsp:forward page="/sindicato/consultaServidor.jsp"/>

Решением было заменить тег jsp тегом jstl:

<c:redirect url="/sindicato/consultaServidor.jsp"/>

И не спрашивайте почему! Потому что у нас есть больше страниц jsp с этим тегом jsp (jsp:forward) без проблем.

person Gilberto    schedule 25.07.2012

java.lang.VerifyError:

Легкий ж/д

Это из-за встроенного компилятора tomcat.

Компилятор Java из Eclipse JDT включен в качестве компилятора по умолчанию. Это расширенный компилятор Java, который загружает все зависимости из загрузчика классов Tomcat, что очень помогает при компиляции на больших установках с десятками JAR-файлов. На быстрых серверах это позволит выполнять циклы перекомпиляции менее секунды даже для больших страниц JSP.

Если обнаружены какие-либо такие проблемы, следуйте приведенному ниже обходному пути.

Apache Ant, который использовался в предыдущих выпусках Tomcat, можно использовать вместо нового компилятора, просто удалив файл lib/ecj-*.jar и поместив файлы ant.jar и ant-launcher.jar из последнего дистрибутива Ant. в папке либ.

person SathishKumar Balasundaram    schedule 25.03.2016