Maven打包Jar后缺失引用库:运行时找不到外部Jar类
这问题我太熟了——你在Eclipse里手动通过Build Path加的外部Jar,和Maven的依赖管理完全是两套独立的体系!Eclipse能识别这些Jar是因为它自己的构建路径配置,但Maven打包的时候只认pom.xml里声明的依赖,所以这些手动添加的Jar根本没被包含到最终的可执行Jar里,运行时自然会报类找不到的错误。
下面给你几个靠谱的解决方案,按推荐程度排序:
方案1:将外部Jar安装到本地Maven仓库(推荐)
把外部Jar注册到本地Maven仓库,这样Maven就能像管理其他中央仓库依赖一样处理它,最规范也最不容易出问题。
打开终端,执行下面的命令(替换成你的Jar信息):
mvn install:install-file \ -Dfile=${project.basedir}/jars/xxx.jar \ -DgroupId=com.yourcompany \ -DartifactId=your-external-lib \ -Dversion=1.0.0 \ -Dpackaging=jar
参数说明:
-Dfile:你的外部Jar的相对路径(用${project.basedir}指向项目根目录,比绝对路径更灵活)-DgroupId/-DartifactId/-Dversion:自定义的依赖坐标,方便后续在pom.xml里引用
然后在pom.xml里添加这个依赖:
<dependency> <groupId>com.yourcompany</groupId> <artifactId>your-external-lib</artifactId> <version>1.0.0</version> </dependency>
之后重新执行mvn clean package,打包出来的Jar就会正确识别这个依赖,运行时也能找到对应的类了。
方案2:在pom.xml中配置System依赖(适合临时场景)
如果不想安装到本地仓库,可以直接在pom.xml里声明system类型的依赖,指定Jar的本地路径:
<dependency> <groupId>com.yourcompany</groupId> <artifactId>your-external-lib</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/jars/morejars/yyy.jar</systemPath> </dependency>
注意:${project.basedir}是Maven内置变量,能自动适配不同环境的项目路径。
但仅仅这样还不够,Maven默认不会把system依赖打包到可执行Jar里,你需要额外用maven-shade-plugin把所有依赖打包成一个Fat Jar(见方案3),否则运行时还是会缺类。
方案3:打包成包含所有依赖的Fat Jar(彻底解决类路径问题)
把所有依赖(包括本地仓库的依赖和外部Jar)全部打包到一个可执行Jar里(俗称Fat Jar),这样运行时就不会有类找不到的问题了。推荐用maven-shade-plugin来实现:
在pom.xml的build节点下添加插件配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- 替换成你的主类全限定名 --> <mainClass>com.yourcompany.YourMainClass</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
配置好后执行mvn clean package,会生成一个带-shaded后缀的Jar文件,直接用java -jar target/project-shaded.jar运行就可以了——所有依赖都包含在这个Jar里,不会再报类找不到的错误。
最后再提醒一句:别再依赖Eclipse的Build Path来管理外部Jar了,Maven的依赖管理才是项目构建的核心,所有依赖都应该在pom.xml里声明,这样不管是打包、CI/CD还是换其他开发环境,都能保持一致。
内容的提问来源于stack exchange,提问作者tenticon

