19

当我在 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) 没有引发错误。从第一个 JSP 到第二个 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
webapp 的 WEB-INF\lib 不包含 servlet、jsp 或 JSTL jar。它包含许多应用程序依赖项和 spring jar(我们使用 spring MVC)。

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

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

4

6 回答 6

11

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

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

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

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

更新 2012/05/30 你有jasperor javax.elor el-apijar inWEB-INF/lib吗?如果是这样,请将其/它们也删除。

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

于 2012-04-02T20:47:08.183 回答
4

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

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

于 2012-05-27T18:10:39.677 回答
2

您是否尝试过禁用拆分验证程序-XX:-UseSplitVerifier

这是 JVM 选项的参考: http ://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

我已经看到与 Java 7 和 VerifyError 类似的东西。

于 2012-04-26T00:43:40.140 回答
1

尝试打印类路径 ( System.out.println("java.class.path");) 比较 tomcat5 和 tomcat7 的类路径。检查类路径有什么区别。

于 2012-05-02T12:23:22.033 回答
0

这发生在我的 Tomcat 6.0.35 上,并且只是在一个 jsp 页面中,它只有:

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

解决方案是用 jstl 标签替换 jsp 标签:

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

不要问为什么!因为我们有更多带有该jsp标签(jsp:forward)的jsp页面没有问题。

于 2012-07-25T15:19:25.027 回答
0

java.lang.VerifyError:

易W/A

这是因为内置的 tomcat 编译器。

来自 Eclipse JDT 的 Java 编译器作为默认编译器包含在内。它是一个高级 Java 编译器,可以从 Tomcat 类加载器加载所有依赖项,这在编译具有数十个 JAR 的大型安装时将有很大帮助。在快速服务器上,即使是大型 JSP 页面,这也将允许亚秒级的重新编译周期。

如果发现任何此类问题,请遵循以下解决方法

可以使用 Apache Ant(在以前的 Tomcat 版本中使用)来代替新的编译器,只需删除 lib/ecj-*.jar 文件,并从最新的 Ant 发行版中放置 ant.jar 和 ant-launcher.jar 文件在 lib 文件夹中。

于 2016-03-25T09:33:41.983 回答