Tomcat 7生产服务器上的VerifyError错误可能是由于Apache Commons Logging 1.0.4引起的。

21

我正在Tomcat 7上开发Web应用。在我的本地Tomcat版本上,一切都很好,但是当我将其部署到生产服务器上时,它会抛出此异常。

java.lang.VerifyError: (class: org/apache/commons/logging/impl/Log4JLogger, method: fatal signature: (Ljava/lang/Object;Ljava/lang/Throwable;)V) Incompatible object argument for function call
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2595)
    at java.lang.Class.getConstructor0(Class.java:2895)
    at java.lang.Class.getConstructor(Class.java:1731)
    at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:410)
    at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529)
    at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
    at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
    at org.apache.fop.apps.FopFactory.<clinit>(FopFactory.java:68)
    at cz.soma.tomcat.generator.DokumentaceUtils.createPdfDocument(DokumentaceUtils.java:818)
    at cz.soma.tomcat.generator.FileFactory.createPdfDocument(FileFactory.java:58)
    at cz.soma.tomcat.generator.Generator.doPost(Generator.java:111)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)

当我尝试使用Apache FOP 1.0的FopFactory.newInstance();时,会抛出错误。之后,它会尝试使用LogFactory.getLog(FopFactory.class);。这导致调用了logClass.getConstructor(logConstructorSignature);,其中logConstructorSignature包含一个String.class。(至少在我的本地机器上是这样)

try {
    logConstructor = logClass.getConstructor(logConstructorSignature);
    return (logConstructor);
} catch (Throwable t) {
    throw new LogConfigurationException
        ("No suitable Log constructor " +
         logConstructorSignature+ " for " + logClassName, t);
}

接下来是java.lang.Class函数和抛出的异常。

你有没有想过为什么这个错误只在生产服务器上抛出,而不是在我的本地机器上?


似乎您的本地环境和生产环境之间的commons-logging版本存在问题。您是如何部署应用程序的? - Evgeny Veretennikov
通过将战争包发送到Tomcat Web应用程序管理器,如何实现? - Přemysl Šťastný
2个回答

3
你们生产环境的Tomcat服务器上common lib目录下可能有不同版本的日志记录jar包。请让相关人员检查\lib目录,确认是否存在日志记录jar包。要么删除那些jar包,以便使用本地应用程序jar包,要么确保在应用程序中定义相同版本的依赖项。
如果要在本地尝试复制,请将生产lib目录中的一组jar包复制到您的本地安装中。

3

为什么会出现这个错误(java.lang.VerifyError)?

java.lang.VerifyError 是由于编译时所使用的库与运行时所使用的库(在你的生产服务器上)不同而导致的结果。

建议#1:

您可以使用 commons-logging-1.1.1.jar 替代 commons-logging-1.0.4.jar。然后重新构建项目并检查。

资源链接: http://www.java-samples.com/showtutorial.php?tutorialid=674

建议#2:

如果您正在使用 Maven,则可以在您的 pom.xml 中添加此依赖项

<dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
</dependency>

并从您的pom.xml中删除以下依赖项

<dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.0.4</version>
</dependency>

资源链接: 获取 java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory 异常

建议#3:

templatetypedef 探究了这个问题并提供了两种解决方案。

VerifyError 通常表示你加载了一个有缺陷的类文件或引用了另一个已经改变导致其他类文件中的代码不再有效的类文件。例如,如果你编译了一个类文件,其中引用了另一个类中的方法,然后修改了那个方法的签名并重新编译了第二个类文件,那么你就会得到这种错误。

我建议进行一次清理构建并查看是否解决了此问题。如果没有,请检查是否使用了最新的 JAR 文件和源文件。

资源链接: https://dev59.com/llXTa4cB1Zd3GeqP2YRP#5411528

建议#4:

如果你本地和生产服务器之间的 JDK 版本不匹配,则尽可能使其相同。您还可以尝试使用不同的 JDK 版本和在不同的计算机上编译。

资源链接: 获取 java.lang.VerifyError 的原因

希望这些能帮到您。


我不知道为什么,但当我将它转换为 Maven 项目并设置依赖项时,问题已经解决了。谢谢。 - Přemysl Šťastný

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接