Maven带依赖可执行Jar运行时抛出NoClassDefFoundException问题
嘿,这种编译过但运行时丢类的问题我可太熟了!十有八九是打包环节没把依赖正确带进去,或者依赖的配置有小坑。咱们一步步来排查解决:
默认的Maven jar插件只会打包你自己写的代码,不会把依赖包也塞进去。这时候你得用专门的插件来构建包含所有依赖的可执行Jar,推荐用maven-shade-plugin,配置起来简单还靠谱。
把这段配置加到你pom.xml的<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"> <!-- 这里替换成你的主类全路径,比如 com.example.MyMainClass --> <mainClass>你的主类完整路径</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
然后跑mvn clean package,去target目录找带-shaded后缀的Jar,用这个Jar运行试试,应该能解决大部分依赖缺失的问题。
如果你的依赖被设成了provided或者test,那编译的时候Maven会用它,但打包时会直接忽略。打开pom.xml看看出问题的那个依赖,确保它的scope是compile(默认就是这个,不用特意写),要是不小心写成了其他scope,赶紧改回来:
<dependency> <groupId>你的依赖groupId</groupId> <artifactId>你的依赖artifactId</artifactId> <version>依赖版本号</version> <!-- 别写<scope>provided</scope>或者<scope>test</scope>,除非你确定运行环境自带这个依赖 --> </dependency>
有时候你以为把依赖装到本地仓库了,但可能Jar本身损坏了,或者里面根本没那个缺失的类。去本地仓库的对应路径(一般是~/.m2/repository/[groupId]/[artifactId]/[version]),解压那个Jar看看有没有你找不到的类。如果确实没有,重新安装一遍依赖:
mvn install:install-file -Dfile=/你的依赖Jar路径/xxx.jar -DgroupId=xxx -DartifactId=xxx -Dversion=xxx -Dpackaging=jar
如果你没打包成包含依赖的Jar,手动用java -jar运行的话,肯定会找不到依赖。要么用上面的插件打包成胖Jar,要么手动指定完整的classpath:
java -cp "你的项目Jar.jar:~/.m2/repository/xxx/xxx/xxx/xxx.jar" 你的主类全路径
不过这种方式太麻烦,还是推荐用打包插件一步到位。
按照上面的步骤挨个排查,应该能搞定这个NoClassDefFoundException的问题!
内容的提问来源于stack exchange,提问作者Prasad

