当我在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。不过,这是另一天的目标。
更新3
发现此问题不在tomcat 7.0.12,7.0.14,7.0.16中,而是从7.0.19开始。发布到tomcat用户邮件列表。得到的答复可能是日食JDT编译器出错了。通过用tomcat 7.0.16的JDT编译器替换tomcat 7.0.23 / 27中的编译器和LO& BEHOLD,一切都很好。我打算写一些Eclipse JDT编译器团队(如果有的话)并发布有关此错误的信息。
答案 0 :(得分:11)
此错误表示已针对特定Servlet / JSP / JSTL实现编译JSP,但Tomcat尝试使用ClassPath中提供的其他实现/版本加载已编译的类。
可能是因为你的WAR包含带有servlet,jsp和/或jstl API和/或实现的jar文件。由于使用的版本与Tomcat 5.5的版本匹配,它可以在那里工作,但在最近的实现中失败了。
您必须在Maven POM中为此类依赖项设置scope到provided
,以便从WAR WEB-INF/lib
中排除这些jar。
要验证即时编译的代码是否不加载备用依赖项,您应该使用-verbose:class
运行Tomcat。错误之前的最新行可能有助于猜出错误。
更新2012/05/30
您在jasper
中有javax.el
或el-api
或WEB-INF/lib
jar吗?如果是这样,也将它/它们移除。
您使用的taglib也可能专门为Tomcat 5.5 Servlet 2.3 API编译,并在Tomcat 7时中断。
答案 1 :(得分:4)
错误非常明显:jasper中存在创建字节码的错误。生成的代码不会清除堆栈框架Inconsistent stack height 0 != 1
您可能会尝试将代码混乱,拆分为方法,在此处移动线条,然后错误可能会消失。 你也可以从web.xml(通常在conf中的某个地方)发布jsp servlet的相关信息(匹配* .jsp)来检查编译器参数吗?
答案 2 :(得分:2)
您是否尝试停用拆分验证程序:-XX:-UseSplitVerifier
以下是JVM选项的参考:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
我见过类似Java 7和VerifyError的内容。
答案 3 :(得分:1)
尝试打印类路径(System.out.println("java.class.path");
)
比较tomcat和tomcat的类路径7.检查类路径的区别。
答案 4 :(得分:0)
我在Tomcat 6.0.35上发生了这种情况,只在一个jsp页面中,它只有:
<jsp:forward page="/sindicato/consultaServidor.jsp"/>
解决方案是用jstl tag替换jsp标签:
<c:redirect url="/sindicato/consultaServidor.jsp"/>
不要问为什么!因为我们有更多带有jsp标签的jsp页面(jsp:forward)没有问题。
答案 5 :(得分:0)
java.lang.VerifyError的:
简易W / A
这是因为内置的tomcat编译器。
Eclipse JDT中的Java编译器作为默认编译器包含在内。它是一个高级Java编译器,它将从Tomcat类加载器加载所有依赖项,这将在编译具有数十个JAR的大型安装时提供极大的帮助。在快速服务器上,这将允许甚至大型JSP页面的亚秒级重新编译周期。
如果出现任何此类问题,请按照以下解决方法进行操作
通过简单地删除lib / ecj - * .jar文件,并放置ant.jar和ant-launcher.jar文件,可以使用以前的Tomcat版本中使用的Apache Ant代替新的编译器。 lib文件夹中的最新Ant分发。