Tomcat 7 生产服务器上的 VerifyError 可能由 Apache Commons Logging 1.0.4 引起

VerifyError on Tomcat 7 production server probably caused by Apache Commons Logging 1.0.4

我正在 Tomcat 7 上开发 webapp。在 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)

当我尝试 FopFactory.newInstance();(来自 Apache FOP 1.0)时,抛出了错误。之后,它会尝试 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 函数并抛出异常。 你知道为什么错误只在生产服务器上抛出,而不是在我的本地机器上吗?

您可能在生产 Tomcat 服务器上的公共 lib 目录中有不同版本的日志记录 jar。让某人检查 \lib 目录并查看 lib 目录中是否有任何日志记录 jar。要么删除这些 jar,以便使用您的本地应用程序 jar,要么确保在您的应用程序中定义相同版本的依赖项。

如果您想尝试在本地复制,请将生产 lib 目录中的一组 jar 复制到您的本地安装。

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

java.lang.VerifyError 将是针对与运行时(在生产服务器中)使用的库不同的库进行编译时的结果。

建议#1:

您可以使用 commons-logging-1.1.1.jar 而不是 commons-logging-1.0.4.jar。然后重建你的项目并检查。

资源 Link: 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>

资源 Link: Getting java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory exception

建议#3:

templatetypedef 挖掘了问题并给出了 2 个解决方案

A VerifyError usually means that you loaded in a class file that is somehow malformed or which references another class file that has changed in a way that causes the code in another class file to no longer be valid. For example, if you compiled a class file that referenced a method in some other class, then independently modified and recompiled the second class after altering that method's signature, you'd get this sort of error.

I'd suggest doing a clean build and seeing if this issue goes away. If not, check whether you're using up-to-date JARs and source files.

资源 Link:

建议#4:

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

资源 Link: Causes of getting a java.lang.VerifyError

希望对您有所帮助。