Maven项目终端运行jar包出现ClassNotFoundException异常如何解决
问题成因
默认情况下mvn package命令生成的jar包仅包含你的项目本身编译产生的.class文件,不会自动引入项目依赖的第三方jar包(比如报错中提到的commons-fileupload组件)。
IntelliJ运行项目时会自动将所有Maven管理的依赖加入运行时的CLASSPATH(也就是JVM加载类文件时的搜索路径,你的理解是完全正确的),因此不会出现类找不到的问题。而你直接执行java -jar server.jar时,JVM默认只会从当前执行的jar包中搜索类,没有加载第三方依赖的路径,就会连续出现ClassNotFoundException异常。
修复方案
这里提供两种常用的解决思路,均通过Maven插件自动完成依赖管理,不需要你手动整理依赖jar包:
方案1:打包含所有依赖的可执行Fat Jar(最常用)
这种方式会把你项目所有的第三方依赖和你自己的代码打包进同一个jar文件,直接可以运行。推荐使用maven-assembly-plugin插件实现,在你的pom.xml中加入如下配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 配置你的项目主类,替换为你实际main方法所在类的全限定名 --> <archive> <manifest> <mainClass>com.example.YourMainClass</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
配置完成后执行mvn clean package,在target目录下会生成名称带jar-with-dependencies后缀的jar包,直接执行java -jar xxx-jar-with-dependencies.jar即可正常运行。
如果你的项目存在依赖冲突、类重复的问题,可以替换为maven-shade-plugin插件,支持更复杂的类重定位、冲突排除能力。
方案2:依赖与主Jar分离存储
如果你不想把所有依赖打进同一个jar,可以将第三方依赖单独放在一个目录,和主jar关联运行:
- 首先配置
maven-dependency-plugin自动把所有依赖导出到lib目录,同时配置maven-jar-plugin指定主类和依赖路径,pom.xml配置如下:
<build> <plugins> <!-- 导出所有依赖到target/lib目录 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.1</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> <!-- 配置主jar的manifest信息,指定主类和依赖路径 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <!-- 替换为实际的主类全限定名 --> <mainClass>com.example.YourMainClass</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build>
- 执行
mvn clean package后,target目录下会生成你的主jar包和lib目录,将二者放在同一级目录下,执行java -jar 你的主jar包名.jar即可正常运行。 - 你也可以不配置manifest,手动指定CLASSPATH运行:
- Linux/Mac环境:
java -cp "server.jar:lib/*" com.example.YourMainClass - Windows环境:
java -cp "server.jar;lib/*" com.example.YourMainClass
- Linux/Mac环境:
内容的提问来源于stack exchange,提问作者Kass224
相关产品推荐
相关产品推荐

