运行Jar包时出现ClassNotFoundException/NoClassDefFoundError问题求助
解决Jar包运行时的ClassNotFoundException和NoClassDefFoundError问题
这问题我太熟了!你在IntelliJ里能正常运行,是因为IDE会自动帮你把项目依赖的所有类都加载到classpath里,但你直接用Maven默认打包出来的Jar,只包含了你自己写的代码,第三方依赖(比如slf4j)根本没被打包进去,运行时JVM找不到这些类,自然就抛出异常了。
下面给你两个最常用的解决方案,都是通过Maven插件把依赖一起打包成可执行Jar:
方案一:使用maven-assembly-plugin
这个插件会把你的代码和所有依赖打包成一个包含所有内容的Jar包,步骤如下:
- 在你的
pom.xml里添加插件配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <configuration> <!-- 指定主类,让Jar可以直接运行 --> <archive> <manifest> <mainClass>你的包名.Main</mainClass> </manifest> </archive> <descriptorRefs> <!-- 该引用会自动打包所有依赖 --> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </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 你的项目名-版本号-jar-with-dependencies.jar
方案二:使用maven-shade-plugin(更适合处理依赖冲突)
如果你的项目依赖存在版本冲突(比如多个依赖引用了不同版本的slf4j),shade插件能帮你合并、重命名类,避免冲突。配置如下:
- 在
pom.xml里添加插件:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.5.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- 指定主类 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>你的包名.Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
- 同样执行
mvn clean package,然后运行target目录下的Jar包(这个插件生成的Jar没有特殊后缀,就是普通的项目Jar)。
额外注意点
- 检查你的
pom.xml里依赖的<scope>,如果用了provided,这个依赖不会被打包进去,运行时就会找不到类。slf4j这类核心依赖应该用默认的compile范围。 - slf4j只是日志门面,你还需要绑定具体的日志实现(比如logback-classic或者log4j-slf4j-impl),虽然没加不会直接导致类找不到,但可能会有运行时警告,建议一起配置。
内容的提问来源于stack exchange,提问作者riorio
相关产品推荐
相关产品推荐

