写点什么

依赖 jar 没有传递,导致找不到类文件而启动失败了

作者:程序员小航
  • 2021 年 12 月 14 日
  • 本文字数:1598 字

    阅读完需:约 5 分钟

前言

最近频繁遇到找不到类文件错误。


Caused by: java.lang.NoClassDefFoundError:xxx


就这个家伙。


但是我本地启动服务是正常的,前前后后经历了


惊讶 -> 疑惑 -> 烦躁 -> 暴躁 -> 心塞 -> 欣喜


在短短的小半天内,感觉心情像过了一个过山车+大摆锤,结束了,脑袋都是晕的。


关键是本地是正常的!



现在,请跟随我的视角,来看看这个让人心态差点爆炸的异常吧!

遇到问题

在一顿噼里啪啦之后,代码写完,Junit 测试完毕、接口文档 Upload 到 YApi 完毕。果断发布 dev 环境!


直接进入启动重试!(PS:通过发布平台发布的)


这时候第一反应:本地启动一下试试!


web started successfully
复制代码


本地正常啊!


肯定是我启动姿势不正确,重新发布一下!



实锤了,和启动姿势没关系!

从淡定到暴躁

当然是看启动日志了。


PS: 服务没起来,只能 ssh 到服务器看日志。


Caused by: java.lang.ClassNotFoundException:xxxCaused by: java.lang.NoClassDefFoundError:xxx
复制代码


就这俩哥们,类找不到,奇了怪了。


这个类是通过三方 jar 包依赖进来的,我在 IDEA 里面 ⌘ + B 还能进入源码!


这我不禁怀疑是不是因为开发环境使用的 Docker 容器的原因。


发布其他分支,是可以的。



莫非就是因为我引入了一个其他小伙伴提供的 jar,导致我现在用不了!


又是一顿调整依赖!


还不行!


难道是我引入的引来版本不对?


从其他项目找一找怎么用的!


依然不行!


难道是他的 jar 包里面又依赖了很多其他的?


试着 exclusion 掉其他依赖!


依然不行!


是我本地 jar 缓存?


删除本地磁盘上的 jar 试试?


😠😠😠!


解决方案就在灵光一闪

虽然 dev 用的是容器,咱拉不下来 jar 包。但是我可以本地打个包试试!


clean package


得到一个 jar 包


jar -xvf xxx-web-1.0.0-SNAPSHOT.jar
复制代码


进到 BOOT-INF/lib 里面


% > ls | grep user
复制代码


竟然啥也没有!



既然是打包没有打进去,那就看一下 mvn 依赖树的问题吧!

解决问题


web 启动失败,是因为 service 添加的依赖,没有传递到 web,所以 web 打包没有打进去那个类。


注意,这里可以正常打包,本地环境可以正常启动。

奇怪吧!


现在进入解决方式:


  • 查看 maven 依赖树


进入到 web module,执行以下命令。


mvn dependency:tree>tree.txt
复制代码


有这么一行错误:


[WARNING] The POM for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
复制代码


问题描述的很清晰,依赖传递失败,因为啥依赖传递失败呢?


再开启 debug 打印下错误:


mvn -X dependency:tree>tree.txt
复制代码


[WARNING] The POM for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT is invalid, transitive dependencies (if any) will not be available: 2 problems were encountered while building the effective model for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT[ERROR] 'dependencies.dependency.version' for com.alibaba:easyexcel:jar is missing. @ [ERROR] 'dependencies.dependency.version' for com.xxx:cache:jar is missing. @ 
复制代码


说是因为下面两个 jar 的 version 找不到,所以会导致依赖传递失败。


PS: 我所有的依赖版本都是在父 POM 进行维护的,子 module 只有依赖 groupId 和 artifactId。


所以归根到底,是因为父 POM 的版本没有传递下去!


仔细一瞅,发现父 POM 的版本是 1.0.0,各个 module 的 parent 节点的属性也是 <version>1.0.0</version>


之前都是 SNAPSHOT 版本,后来因为公司的 nexus 配置了自动清除长时间不用的 SNAPSHOT 版本的依赖,我就去掉了 SNAPSHOT。

父 POM deploy 到私服的就是一个空的项目,里面就一个 POM 文件。


最后升级了一下父 POM 的版本,重新 deploy 一下,再改改各个 module 的依赖版本。


大功告成!

总结

本文主要是含泪记下一个苦逼的问题排查过程。害,竟然没有第一时间想到原因!



下次再遇到记得 mvn -X dependency:tree>tree.txt 看下依赖树!


我的实践已经证明了:重启、清缓存、排除依赖都是没用的!

发布于: 2 小时前阅读数: 7
用户头像

个人公众号:『 程序员小航 』 2020.07.30 加入

某不知名互联网公司 Java 程序员一枚。记录工作学习中的技术、开发及源码笔记;分享生活中的见闻感悟。

评论

发布
暂无评论
依赖 jar 没有传递,导致找不到类文件而启动失败了