eclipse maven 项目第三方 jar 包 ClassNotFound 的问题

eclipse maven 项目第三方 jar 包 ClassNotFound 的问题

今天同事使用 Eclipse 启动了一个 Maven 项目,在运行过程中出现了 ClassNotFound 的错误,本以为是个很简单的问题,结果他花了较长时间却一直没能解决。我帮他看了下,结果一下子也是没找到问题所在,后来陆陆续续花了近半个小时的时间才把问题解决,期间碰到了在使用 Eclipse 过程中出现的好几个问题,在这里记录一下解决的过程。

  • eclipse maven 项目第三方 jar 包 ClassNotFound 的问题
    • 起因
      • - ClassNotFoundException
    • 一些想法
      • - Maven 项目第三方 jar 包的管理方式
      • - Maven Web 项目的检出及转换
      • - Eclipse 的 Web Deployment Assembly 相关参数
    • 解决


起因

- ClassNotFoundException

项目在生成 pdf 文件的时候出现了 org.icepdf.core.pobjects.Document 的 ClassNotFound 异常,说明类加载器没有找到相应的类,原因有多种

1. 一种情况是这个类确实不存在,项目没有引入相关类的 jar 包;

2. 也有可能是这个类存在多个版本,加载器优先使用了较低版本的类;

3. 还有可能是编译时使用了较高版本的jdk,而部署环境的jdk版本较低,也可能会报这个错误(没遇到过);

4. 也有可能是文件权限的问题,这种情况比较少见。

我看了下出问题的类,这个类来自第三发的 jar 包,没有使用 Maven 管理,在 /WEB-INF/other-lib/ 路径下,通过 Add to Build Path 的方式引入到项目中,也不存在有多个版本 jar 包的情况。jdk版本和文件权限的问题也都不是。那是什么地方出问题了呢。我想到是不是这样引入的 jar 包在 Maven 管理的情况下会有什么问题,考虑下 maven 管理第三方 jar 包的方式。

一些想法

- Maven 项目第三方 jar 包的管理方式

在开发过程中,不可避免地会参考学习使用网上的开源代码,其中可能会使用到第三方的 jar 包,这些 jar 包在 Maven 中央仓库中没有,需要使用其他的方式引入到我们的项目中

1. 常见的第三方 jar 包的管理方式是使用 mvn 命令进行本地注册,
    配置好 maven 环境变量后,可以直接在终端中使用 mvn 命令进行本地注册安装 jar 包。
    mvn install:install-file 
    -DgroupId=com.gft -DartifactId=CASClientU -Dversion=1.6 -Dpackaging=jar 
    -Dfile=D:\MavenRepository\com\gft\CASClientU\1.6\CASClient_1.6.jar
2. 对于公司内部服务器搭建有私有仓库的情况,直接在仓库里配置上传第三方 jar 包即可。
3. 最简单的方式就是通过 Add to Build Path 引入 jar 包。

本项目引入 jar 包的方式就是第三种。本来同事使用的是第一种方式,本地注册完之后在 pom 文件中添加依赖描述。但是这种方式需要每个开发人员都对此 jar 包进行本地注册安装。对于不同的开发环境来说很麻烦,所以我删掉了依赖描述,改为放入 /WEB-INF/other-lib/ 路径下,通过 Add to Build Path 引入,项目编译错误也都消失了。看了下项目配置里的 Java Build Path 相关参数,确实也出现了这几个 jar 包,那为什么还会出这种错误。我认为是 Eclipse 本身的问题,于是将项目重新检出。

- Maven Web 项目的检出及转换

由于是 Maven 项目,从 Git 检出为一般项目(general project)后,需要通过 Configure -> Convert to Maven Project 操作将项目转换为 Maven 项目结构。完成这步操作后(期间会从 Maven 仓库下载依赖 jar 包,时间较长),需要对项目进行配置

1. 配置 Project Facets,web 项目要保证勾选了 Dynamic Web Module 与 Java,
    并且其版本分别与 web.xml 中 web-app 及项目的 jdk 版本一致。
2. 查看 Deployment Assembly,确认其中的 Source 路径和对应的 Deploy Path 是否正确
3. 将第三方 jar 包通过 Add to Build Path 引入到项目中

项目检出后,pom.xml 文件报错,显示是第一行出现错误,错误信息显示无法识别该文件,不断调整配置项目,错误仍然存在。网上的说法不外乎就是配置 Project Facets 、修改 jdk 版本以及配置 maven 插件指定编译所用的 jdk 版本。对于这种很明确自己没有问题的但 Eclipse 仍然报错的情况,那有可能是 Eclipse 本身的问题。尝试将项目关闭,再打开,依然报错。重启 Eclipse ,再看 pom 文件,错误消失。可能是因为项目检出转化后 Eclipse 仍然没有将其识别为一个 Maven 项目,导致了错误。

但是,在把这个问题解决后,启动项目,却出现了 spring 容器启动失败的异常,java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener,这就很奇怪了。

- Eclipse 的 Web Deployment Assembly 相关参数

查看了 Java Build Path 的 Libraies 相关参数,没有问题,其中第三方 jar 包、JRE System Library、Maven Dependencies 都有,很正常。
eclipse maven 项目第三方 jar 包 ClassNotFound 的问题_第1张图片
那么这应该是在项目编译后,在 Server 中部署出现了问题,竟然连 Maven 管理的 Spring 相关的 jar 包都没有找到,那应该去查看部署相关的路径配置参数,查看 Eclipse 中的 Web Deployment Assembly

1. Source 中至少应该有 /src/main/java、/src/main/resources、/src/main/webapp 这三项,
    对应的 Deploy Path 分别是 WEB-INF/classes、WEB-INF/classes、/
2. Source 中还应该有 Maven Dependencies ,对应的 Deploy Path 是 WEB-INF/lib,
    这样在编译项目的时候才会将 Maven 管理的 jar 包放入到 WEB-INF/lib 路径下。

查看 Web Deployment Assembly 的时候,发现 Source 下没有竟然 Maven Dependencies 库,这样的话 Spring 容器自然就无法启动了。添加上 Maven Dependencies 及对应的 Deploy Path,项目能正常启动。

eclipse maven 项目第三方 jar 包 ClassNotFound 的问题_第2张图片

解决

在修改 Web Deployment Assembly 相关参数的时候我发现,第三方的 jar 包这里面也没有。因为转换 Maven 项目的时候这里应该会自动添加 Maven Dependencies,这次转换出问题了需要我自己手动加上,那么之前通过 Add to Build Path 引入的第三方 jar 包,这里会不会也没有自动加上,这才导致了运行的时候出现了相关类的 ClassNotFound 异常?
尝试在这里添加了 Java Build Path Entries 中那几个之前引入的 jar 包,重启运行,生成 pdf,没有异常出现,问题解决。
eclipse maven 项目第三方 jar 包 ClassNotFound 的问题_第3张图片

你可能感兴趣的:(IDE)