java.lang.VerifyError in tomcat 7.0.23/jdk 1.6.x?

2022-09-02 13:38:53

当我在Linux(java 1.6.x)上将maven 3.0.3内置的webapp部署到tomcat 7.0.23中并在登录页面中访问发布我的凭据时,我得到了以下错误。pom.xml 引用 servlet 2.5、jsp 2.1 和 JSTL 1.2。

为什么我会得到这个错误?我能做些什么来避免它?

我在同一个tomcat实例上部署了其他.war文件,并且在这些应用程序中从未遇到过此问题。

我执行http GET的第一个JSP(login.jsp)没有抛出错误。从第1个JSP到第2个Jsp(ChLogin.jsp)的POST遇到了问题。

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

根源

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 应用程序的 WEB-INF\lib 不包含 servlet、jsp 或 JSTL jar。它包含许多应用程序依赖项和弹簧罐(我们使用弹簧MVC)。

更新 2
我们不预编译 JSP。不过,这是另一天的目标。

UPDATE 3
发现此问题不在 tomcat 7.0.12、7.0.14、7.0.16 中,而是从 7.0.19 开始。发布到tomcat用户邮件列表。得到的答复是,可能是eclipse JDT编译器出了问题。通过将tomcat 7.0.23/27中的编译器替换为tomcat 7.0.16的JDT编译器和LO&BEHOLD,验证情况确实如此,一切都很好。我打算写信给Eclipse JDT编译器团队(如果有的话)并发布有关此错误的信息。


答案 1

此错误意味着 JSP 已针对特定的 Servlet/JSP/JSTL 实现进行了编译,但随后 Tomcat 尝试使用 ClassPath 中提供的其他实现/版本加载已编译的类。

发生这种情况可能是因为您的 WAR 包含带有 servlet、jsp 和/或 jstl API 和/或实现的 jar 文件。由于使用的版本与Tomcat 5.5 imlementation相匹配,因此它可以在那里工作,但在最近的实现中失败。

您必须将范围设置为Maven POM中此类依赖项的范围,以从WAR中排除该jar。providedWEB-INF/lib

要验证动态编译的代码是否不加载备用依赖项,应使用 运行 Tomcat。错误之前的最新行可能有助于猜测错误所在。-verbose:class

更新 2012/05/30你有任何或或罐子吗?如果是这样,请将其/它们也删除。jasperjavax.elel-apiWEB-INF/lib

您使用的 taglib 也可能是专门为 Tomcat 5.5 Servlet 2.3 API 编译的,并在 Tomcat 7 时中断。


答案 2

错误非常明显:在创建字节码的jasper中存在一个错误。生成的代码不会清除堆栈帧属性Inconsistent stack height 0 != 1

您可以尝试随机排列代码,拆分为方法,在这里和那里移动行,错误可能会消失。另外,你能从web.xml(通常在conf的某个地方)发布jsp servlet的相关信息(匹配*.jsp)来检查编译器参数吗?