【问题标题】:java.lang.VerifyError: Incompatible argument to functionjava.lang.VerifyError:函数的参数不兼容
【发布时间】:2011-06-19 15:18:51
【问题描述】:

我有一个 mavenized Spring 3 项目,可以在一台机器上构建和运行良好。 完全相同项目在第二台机器上构建良好,但是当我尝试点击一个页面(在另一台机器上运行良好的页面)时,我得到以下堆栈跟踪:

java.lang.VerifyError: (class: org/apache/jsp/tag/web/generate_002dvalidation_tag, method: _jspx_meth_c_005fset_005f13 signature: (Ljavax/servlet/jsp/tagext/JspTag;Ljavax/servlet/jsp/PageContext;[I)Z) Incompatible argument to function
    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.compiler.TagFileProcessor.loadTagFile(TagFileProcessor.java:635)
    org.apache.jasper.compiler.TagFileProcessor.access$000(TagFileProcessor.java:52)
    org.apache.jasper.compiler.TagFileProcessor$TagFileLoaderVisitor.visit(TagFileProcessor.java:685)
    org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1530)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)
    org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2411)
    org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2417)
    org.apache.jasper.compiler.Node$Root.accept(Node.java:495)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)
    org.apache.jasper.compiler.TagFileProcessor.loadTagFiles(TagFileProcessor.java:703)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:210)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:347)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:327)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:314)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:589)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

我能想到的唯一区别是 Java 的版本。在项目工作的机器上,版本是 6 update 17,而在第二台机器上(项目不工作的地方),版本是 6 update 22。pom 完全一样。

看起来问题集中在一个自定义标签上,但我不知道它是什么。什么可能导致此问题?

更新

我查看了两台机器上的目标目录并注意到以下内容:

  • 在项目不工作的机器上,lib目录有el-api-2.2.jar
  • 在项目所在的机器上,target下有tomcat目录,包含以下内容:
`--tomcat |-- 配置 | |-- tomcat-users.xml | `-- web.xml |-- 日志 |-- 网络应用 `--工作 `-- 本地引擎 `--本地主机 `-- _ |-- 组织 | `--阿帕奇 | `--jsp | |-- 标签 | | `--网络 | | |-- generate_002dvalidation_tag.class | | `-- generate_002dvalidation_tag.java | `-- WEB_002dINF | `--jsp | `-- 星舰 `-- 会话.ser

项目所在的机器上不存在此目录

  • 在项目运行的机器上,target下有一个war目录,在项目不运行的机器上是不存在的(但是两台机器都在下面生成了一个war文件target 目录)

  • 在构建不工作的机器上,war 文件是 4,135,195 字节,而在另一个是 4,104,569 字节。这种差异来自于包含el-api-2.2.jar 文件。

我不确定这是什么意思。

【问题讨论】:

    标签: spring spring-mvc maven


    【解决方案1】:

    虽然 gigadot 提到的原因是正确的,但我肯定会在转到其他内容之前检查以下内容:

    1. 检查我的类路径中的cglibs
    2. 检查我的类路径中的hibernate 版本。

    上述任何一个版本的多个版本或相互冲突的版本很可能会导致与相关问题类似的意外问题。

    【讨论】:

      【解决方案2】:

      超过java版本,我认为问题是由于Java EE库的版本不同造成的。

      是否可能两台机器有不同的应用服务器或不同版本的应用服务器?此外,容器提供的库(如servlet-api.jarjsp-api.jar)是否被打包在战争中?

      【讨论】:

        【解决方案3】:

        根据我的经验,有时验证会导致与泛型相关的复杂事情出错。此外,有时仪器可能会给它带来问题。如果您知道不应该出现验证错误,但仍然出现,则可以使用-noverify 启动选项禁用验证。

        有时它也会因为性能等其他原因而被禁用。

        有关禁用验证的更多详细信息,请参阅this thread

        【讨论】:

          【解决方案4】:

          根据this answer

          java.lang.VerifyError 可以是 编译后的结果 与您使用的库不同 在运行时。

          我建议你在每台机器上编译它并比较war文件中的内容(假设,从stacktrace中,你正在构建war项目)。

          你碰巧在 linux vs Windowsy 上编译它吗?您可能在类路径中拥有具有不同版本的相同库。在不同的操作系统上,加载类的顺序是不同的。正确的可能首先加载到运行 JDK 6u17 的机器上。

          我通常在7zip浏览器中打开war文件并检查是否有不同版本的相同库。一些库使用不同的工件名称,但实际上是相同的,例如spring-bean 和 org.springframework.bean。

          【讨论】:

          • 我在 linux 上编译它们。我会看一下war文件,看看是否有任何差异。
          • 如果项目相同,我希望相同的 maven 版本以相同的方式捆绑它们。您是否碰巧在项目中有任何其他版本的 el-api 不起作用?我不知道问题出在哪里,但我建议您尝试从使用任何 zip 程序都不起作用的 war 文件中删除 el-api-2.2.jar 并部署它以测试它是否真的是因为这个额外的库。顺便说一句,请确保您执行mvn clean 以确保旧版本没有遗留任何东西。
          • 一些IDE支持maven依赖图,你也可以看看el-api是从哪里来的。由于el 是Java EE 的一部分,如果您的servlet 容器已经提供了它,您可能不需要包含它。您只需在 maven 依赖项中声明 el-api 范围为 provided
          • 只是想知道您是否确定在两台机器上都使用了正确的 Java 进行编译。它们都是 JDK SE 还是 EE 还是 OpenJDK?
          • 他们都在运行 Sun 的 JDK。我从不使用 OpenJDK。
          猜你喜欢
          • 2013-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-09
          • 1970-01-01
          • 2016-10-15
          相关资源
          最近更新 更多