【问题标题】:Java ClassNotFoundException for one class, but other one is found一个类的Java ClassNotFoundException,但找到了另一个
【发布时间】:2018-03-09 14:44:22
【问题描述】:

我有一个 Maven 项目,它为通信接口提供低级 API 和基本功能。我还有一些其他的 Maven 项目都依赖于这个项目,并基于低级 API 实现特定的通信。由于这些是 Maven 项目,所以当我将更高级别的项目构建到 .war 文件中时,低级项目会自动包含在 lib 文件夹中作为 .jar 文件,以及所有其他依赖项。

我将此项目部署到 Tomcat 7,它已经托管了其他几个 web 应用程序,每个应用程序都有自己的依赖项。它几乎立即产生了 ClassNotFoundException,缺少低级项目中的一个类。这里有两个奇怪的地方:

  • 报告丢失的类文件在低级项目的.jar文件中
  • 在运行时发现并成功使用了来自同一项目的另一个类文件

是否有可能是某些依赖冲突导致了这种情况?我不确定 Tomcat 的类路径是如何工作的,但据我所知,它以某种顺序包括 Tomcat 的 lib 文件夹和所有 webapps 的 lib 文件夹。这个低级项目需要许多依赖项,如 commons-io、httpclient、log4j 等。所有这些 jar 都存在于我的 webapp 的 lib 文件夹中,但其中一些 jar 在 Tomcat 的 lib 项目中具有不同的版本(例如httpcore-4.3.2.jar 在我的 webapp 中,httpcore-4.0.jar 在 Tomcat 的 lib 文件夹中)。我找不到解释,但有些人提到这种情况可能会导致这种情况。我以前从未遇到过这个问题,在这种 jar 冲突中,我总是遇到 java.lang.VerifyError(或者有时是 ClassNotFoundException,但在这些情况下,实际上某个依赖 jar 文件中缺少该类)。

这种 jar 冲突是否可能导致使用这些 jar 的类根本没有加载?我会觉得这很奇怪。

更新:

抱歉,我忘记了堆栈跟踪。以下是我在打开应用程序时在浏览器中看到的内容:

Mar 09, 2018 2:30:48 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [hu.tsm.ccm.aif.mobilegateway.routes.init] in context with path [/AIFMobileGateway] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoClassDefFoundError: hu.tsm.ccm.vxmlgateway.vxml.AbstractVxmlWalker
    at hu.tsm.ccm.aif.mobilegateway.responses.InitResponse.<init>(InitResponse.java:47)
    at hu.tsm.ccm.aif.mobilegateway.routes.init.doGet(init.java:36)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    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:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2466)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2455)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

这个 hu.tsm.ccm.vxmlgateway.vxml.AbstractVxmlWalker 类存在于 webapp 的 lib 文件夹中的 jar 文件的类路径中。此 jar 中的另一个类,即 hu.tsm.ccm.vxmlgateway.api.Version 正在成功加载。

【问题讨论】:

  • 总是发布堆栈跟踪异常相关问题
  • @Ramanlfc 对不起,我忘了。我现在加了。
  • 每个 webapp WEB-INF/lib 文件夹仅位于该 web 应用程序的类路径中。 Web 应用程序不共享彼此的类路径。因此,无论问题是什么,这都不会涉及。可能涉及一些误导;可能是 AbstractVxmlWalker 所依赖的类实际上不在出现问题的 webapp 的类路径上?

标签: java classnotfoundexception


【解决方案1】:

似乎问题与 Tomcat 启动期间的 jar 文件扫描有关。 Tomcat 启动花了 20 分钟,我怀疑这是由于 jar 扫描,所以我将所有 jar 文件添加到 catalina.properties 文件中的 tomcat.util.scan.DefaultJarScanner.jarsToSkip 属性。 Tomcat 启动后仅 2 分钟,突然间,没有任何其他更改,我的应用程序运行正常。

【讨论】:

    【解决方案2】:

    异常java.lang.NoClassDefFoundError 表示在AbstractVxmlWalker 中用作导入(import 表达式)的类路径中缺少某些类。 AbstractVxmlWalker 的依赖项在类路径中不存在。

    【讨论】:

    • 是的,没错,但是我找不到丢失的东西。实际上不应该丢失任何东西,所有依赖项都打包在 .war 文件中,并且在将该 .war 文件部署到全新的 tomcat 之后,它就可以工作了。这里我的问题是从tomcat的lib文件夹中加载了一些其他版本的依赖项.jar(其他一些部署的webapps需要lib文件夹中的这些文件),因此没有加载打包到我的.war中的.jar文件.在 tomcat 启动期间跳过这些 .jar 文件修复了我的问题,有关详细信息,请参阅我的答案。
    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 2015-07-28
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多