我的 Java Web 应用程序中的 ClassNotFoundException/NoClassDefFoundError [英] ClassNotFoundException/NoClassDefFoundError in my Java web application

查看:17
本文介绍了我的 Java Web 应用程序中的 ClassNotFoundException/NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Java 开发了一个 Web 应用程序.当我将它部署到我的应用程序服务器(Jetty、Tomcat、JBoss、GlassFish 等)时会引发错误.我可以在堆栈跟踪中看到此错误消息:

I developer a web application using Java. When I deploy it to my application server (Jetty, Tomcat, JBoss, GlassFish, etc.) throws an error. I can see this error message in the stacktrace:

java.lang.ClassNotFoundException

java.lang.NoClassDefFoundError

这是什么意思,我该如何解决?

What does this mean and how can I fix it?

推荐答案

这是什么意思?

先来看看java.lang.ClassNotFoundException:

当应用程序尝试通过其字符串名称加载类时抛出:

Thrown when an application tries to load in a class through its string name using:

  • Class 类中的 forName 方法.
  • ClassLoader 类中的 findSystemClass 方法.
  • ClassLoader 类中的 loadClass 方法.
  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader.
  • The loadClass method in class ClassLoader.

但是找不到具有指定名称的类的定义.

but no definition for the class with the specified name could be found.

通常,当尝试以这种形式手动打开连接时会发生这种情况:

Usually, this happens when trying to open a connection manually in this form:

String jdbcDriver = "...'; //name of your driver
Class.forName(jdbcDriver);

或者当您引用属于外部库的类时,奇怪当应用服务器尝试部署应用程序时无法加载该类.

Or when you refer to a class that belongs to an external library and strangely this class cannot be loaded when the application server tries to deploy the application.

来看看java的含义.lang.NoClassDefFoundError(强调我的):

Let's see the meaning of java.lang.NoClassDefFoundError (emphasis mine):

如果 Java 虚拟机或 ClassLoader 实例试图在类的定义中加载(作为正常方法调用的一部分或作为使用 new 表达式创建新实例的一部分),则抛出并且找不到类的定义.

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

在编译当前执行的类时,搜索到的类定义存在,但找不到该定义.

最后一部分说明了一切:该类在编译时即存在,即当我通过 IDE 编译应用程序时,但在运行时即部署应用程序时不可用.

The last part says it all: the class existed at compile time i.e. when I compiled the application through my IDE, but it is not available at runtime i.e. when the application is deployed.

我该如何解决?

在 Java Web 应用程序中,您的应用程序使用的所有第三方库都必须放在 WEB-INF/lib 文件夹中.确保所有必需的库(jar)都放在那里.您可以轻松检查:

In Java web applications, all third party libraries used by your application must go in WEB-INF/lib folder. Make sure that all the necessary libraries (jars) are placed there. You can check this easily:

- <webapp folder>
  - WEB-INF
    - lib
      + jar1
      + jar2
      + ...
  - META-INF
  - <rest of your folders>

此问题通常出现在 JDBC 连接 jar(MySQL、Derby、MSSQL、Oracle 等)或 Web MVC 框架库(如 JSF 或 Spring MVC)中.

This problem usually arises for JDBC connectivity jars (MySQL, Derby, MSSQL, Oracle, etc.) or web MVC frameworks libraries like JSF or Spring MVC.

考虑到一些第三方库依赖于其他第三方库,所以你必须在WEB-INF/lib中添加所有这些才能使申请工作.一个很好的例子是 RichFaces 4 库,您必须手动下载和添加外部库.

Take into account that some third party libraries rely on other third party libraries, so you have to add all of them in WEB-INF/lib in order to make the application work. A good example of this is RichFaces 4 libraries, where you have to download and add the external libraries manually.

Maven 用户的注意事项:除非您将库设置为 provided、testsystem.如果设置为 provided,您有责任在类路径中的某处添加库.您可以在此处找到有关依赖项范围的更多信息:Introduction to the依赖机制

Note for Maven users: you should not experience these problems unless you have set the libraries as provided, test or system. If set to provided, you're responsible to add the libraries somewhere in the classpath. You can find more info about the dependency scopes here: Introduction to the Dependency Mechanism

如果必须在将部署在您的应用程序服务器上的多个应用程序之间共享库,例如用于两个应用程序的 MySQL 连接器,还有另一种选择.与其部署两个带有各自 MySQL 连接器库的 war 文件,不如将该库放置在服务器应用程序的公共库文件夹中,这将使该库位于所有已部署应用程序的类路径中.

In case the library must be shared among several applications that will be deployed on your application server e.g. MySQL connector for two applications, there's another alternative. Instead of deploying two war files each with their own MySQL connector library, place this library in the common library folder of the server application, this will enable the library to be in the classpath of all the deployed applications.

此文件夹因应用程序服务器而异.

This folder vary from application server.

  • Tomcat 7/8:/lib
  • JBoss 7/Wildfly:/standalone/lib
  • Tomcat 7/8: <tomcat_home>/lib
  • JBoss 7/Wildfly: <jboss_home>/standalone/lib

这篇关于我的 Java Web 应用程序中的 ClassNotFoundException/NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆