如何在不面对 java.lang.ClassNotFoundException 的情况下将 JAR 库添加到 WAR 项目?类路径 vs 构建路径 vs /WEB-INF/lib

Posted

技术标签:

【中文标题】如何在不面对 java.lang.ClassNotFoundException 的情况下将 JAR 库添加到 WAR 项目?类路径 vs 构建路径 vs /WEB-INF/lib【英文标题】:How to add JAR libraries to WAR project without facing java.lang.ClassNotFoundException? Classpath vs Build Path vs /WEB-INF/lib 【发布时间】:2016-12-28 02:26:06 【问题描述】:

我应该如何将 JAR 库添加到 Eclipse 中的 WAR 项目而不面对 java.lang.ClassNotFoundExceptionjava.lang.NoClassDefFoundError

CLASSPATH 环境变量似乎不起作用。在某些情况下,我们将 JAR 文件添加到 Eclipse 项目的 Build Path 属性中以使代码编译。我们有时需要将 JAR 文件放在 Java EE Web 应用程序的 /WEB-INF/lib 文件夹中,以使代码在该 JAR 内的类上运行。

我不完全明白为什么CLASSPATH 不起作用,在什么情况下我们应该将 JAR 添加到 Build Path 以及这些 JAR 应该在什么时候放置在 /WEB-INF/lib

【问题讨论】:

【参考方案1】:

CLASSPATH 环境变量仅由 java.exe 命令使用,即使在没有任何 -cp-classpath-jar 参数的情况下调用该命令时也是如此。 CLASSPATH 环境变量会被 Eclipse、Netbeans 和 IDEA 等 IDE 忽略。另见java.lang.ClassNotFoundException in spite of using CLASSPATH environment variable。

构建路径仅适用于编译项目代码所需的库。手动将 JAR 放入 /WEB-INF/lib,或设置部署程序集,或让外部构建系统(如 Maven)在构建期间将 <dependency> 作为 JAR 放入生成的 WAR 的 /WEB-INF/lib 中,仅适用于获取代码以在目标环境上部署和运行所需的库。请注意,您不应该在 /WEB-INF/lib 中创建子文件夹。 JAR 必须放在根目录中。

目标JEE服务器或servletcontainer已经提供了一些库,例如JSP、Servlet、EL等。所以你不需要将这些库的JAR放在/WEB-INF/lib中。而且,它只会导致类加载问题。仅在 Build Path 中(间接)指定它们就足够了。在 Eclipse 中,您通常通过相应地设置 Targeted Runtime 来做到这一点。它将自动以 Build Path 结束。您无需手动将它们添加到构建路径。另见How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?

其他库,通常是第三方库,如 Apache Commons、JDBC 驱动程序和目标 servletcontainer 未提供的 JEE 库(例如,Tomcat 不支持许多开箱即用的 JEE 库,例如 JSF、JSTL、CDI、JPA、 EJB 等),需要以/WEB-INF/lib 结尾。您可以在其中复制并粘贴物理 JAR 文件。您不一定需要在构建路径中指定它。只有当您已经将它作为 用户库 时,您才应该使用 部署程序集 设置来代替它。另见ClassNotFoundException when using User Libraries in Eclipse build path。

如果您使用的是 Maven,那么您需要确保将库标记为 <scope>provided</scope>,如果目标运行时已经提供了这些库,例如 JEE、Servlet、EL 等,以防您部署到WildFly、TomEE 等。这样它们就不会出现在生成的 WAR 的 /WEB-INF/lib 中(并可能导致与服务器捆绑的库发生冲突),但它们最终会出现在 Eclipse 的 Build Path 中(并获取要编译的项目代码)。另见How to properly install and configure JSF libraries via Maven?

【讨论】:

【参考方案2】:

构建路径中的那些 JAR 仅用于构建(编译)过程。如果您导出 Web 应用程序,它们不会包含在最终的 WAR 中(试一试)。

如果您在运行时需要 JAR,您必须将它们放在 WEB-INF/lib 或服务器类路径中。仅当多个 WAR 共享一个公共代码库并且需要访问共享对象(例如 Singleton)时,将 JAR 放置在服务器类路径中才有意义。

【讨论】:

【参考方案3】:

如果您使用的是 Maven

打开项目属性,然后在部署程序集下单击添加...

然后选择Java Build Path Entries并选择Maven Dependencies

【讨论】:

【参考方案4】:

通过设置权限解决。 使用 PySpark 和 Oracle jdbc 有相关问题。该错误并没有说明无法访问该文件,只是说明无法加载该类。

因此,如果有人仍然在挣扎,请检查权限。有些人可能会觉得这很明显。

【讨论】:

【参考方案5】:

我想给出以下链接问题ClassNotFoundException oracle.jdbc.driver.OracleDriver only in servlet, using Eclipse的答案

Ans: 在 Myeclipse 中转到 Server-->左键单击 Myeclipse Tomcat7-->Configure Server Connector-->(Expand)Myeclipse Tomcat7--> Paths-->Prepend to classpath-->Add jar (添加oracle14 jar)-->ok

【讨论】:

【参考方案6】:

本文解释了 Spring Boot 应用程序中的相同问题。还有关于如何下载 Oracle jar 文件并包含依赖项、设置数据源等的有用信息:

Configuring Spring Boot with Oracle

【讨论】:

欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.

以上是关于如何在不面对 java.lang.ClassNotFoundException 的情况下将 JAR 库添加到 WAR 项目?类路径 vs 构建路径 vs /WEB-INF/lib的主要内容,如果未能解决你的问题,请参考以下文章

Pygame:如何在不按任何键的情况下使精灵面对相同的方向

ClassNotFoundException - com.mysql.jdbc.Driver / 导入 mysql-connector-java 后

如何在不面对 java.lang.ClassNotFoundException 的情况下将 JAR 库添加到 WAR 项目?类路径 vs 构建路径 vs /WEB-INF/lib

从 PySpark 3.1.2 连接 Oracle DB - Py4JJavaError 失败

MongoDB - 在不更新的情况下获取另一个字段的值

AOP切面和消息队列支持高并发简易原理