一、起因
C模块是其他项目中的jar);A模块需要用到C模块中的类,通过B模块间接依赖了C模块。此时打包A的时候报错,大致意思是,无法编译使用C模块中的类。
给A模块打包,执行命令:
mvn clean install
出现以下错误:
Error:(8,52) java: 程序包com.demo.utils.common.response不存在
Error:(27,5) java: 找不到符号
Error:(35,5) java: 找不到符号
...
这个“com.demo.utils.common.response”就是上面说C模块中的包。
编译报错,熟悉的味道。。。
截图中报红的Error随便找一个双击一下,跳转到代码中查看下:
尼玛,这代码也没报红啊。开始排查吧~
ps:代码中也报红就简单了,那明显就是缺少jar包,添加对应的maven依赖就行了。
注意:此时报红的地方,都是B模块所依赖jar中的类,即A模块通过B模块间接依赖的类。
二、排查
1. 仔细看错误提示
遇到错误不要慌、不要急,不要放过任何一个报错细节!仔细看,其实会发现截图中的一个警告
摘出来是这样的:
The POM for com.demo:demo-common:jar:1.1.22 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
翻译过来是:demo:demo-common:jar:1.1.22的POM无效,传递依赖项(如果有)不可用,请启用调试日志记录以获得更多细节。
提示很清楚,你依赖的这个common包(就是我们说的B模块)传递依赖项不可用了!也就是说我们A模块,通过B模块间接依赖的包,都不可用了。
为啥不可用,我们看看调试日志吧~
2. debug模式重新install
我们进入到子模块,使用-X参数查看debug信息,比如我刚才打包的子模块是client:
cd client
mvn clean install -X
搜索上面的报错信息:The POM for com.demo:demo-common:jar:1.1.22 is invalid
很容易就能搜到,真正的错误信息就在你搜索的下一行,看截图中标红的位置。
3. 分析错误[ERROR]
当然,每个人的错误可能不一样,我的错误是’dependencies.dependency.version’ for com.demo.xxx:demo-xxx:jar is missing ,意思是demo-xxx这个jar包找不到。demo-xxx(C模块)这个包是B模块依赖的包,为什么会提示缺失呢?
检查B模块的pom.xml
在B模块的pom.xml中,发现demo-xxx(C模块)这个依赖,在B模块的pom.xml中没有配置版本!
<dependency>
<groupId>com.demo</groupId>
<artifactId>demo-xxx</artifactId>
</dependency>
没什么奇怪的,那会使用父项目(即A模块)中定义的版本。但是父项目中定义这个依赖的版本了啊!
注意哈:B模块不一定是使用当前代码父模块中的pom.xml,要看下B模块中pom.xml定义的父模块的版本,如下图。但是我工程的父pom版本却是1.1.0-SNAPSHOT!!!
所以要去maven私服中查看1.0.0这个父pom.xml中到底有没有定义demo-xxx(C模块)这个依赖的版本。
结论
:我去私服上查了下,1.0.0这个父pom.xml中,确实没有定义demo-xxx(C模块)这个依赖的版本,所以导致B模块的pom.xml解析出错(因为C模块不知道使用哪个版本),进而导致B模块依赖的所有包都无法下载!最终导致install A模块的时候报错!
三、解决
- 方式一:在A模块中直接依赖demo-xxx这个jar
原理:因为A模块直接依赖父项目,而且当前父项目的pom.xml代码中也已经声明了demo-xxx.jar的版本,所以A能直接使用。但A依赖B时不能使用,是因为间接依赖不能使用本地pom.xml代码,需要使用私服中真正的pom.xml! - 方式二:升级父项目的版本
在新版本的父pom.xm中声明demo-xxx这个jar的版本,并让B模块使用父项目的新版本,然后A模块依赖B项目的新版本。
四、总结
- 多注意maven报错信息,进而使用-X参数查看debug日志
- 无法下载间接依赖,一般是直接依赖(B模块)的pom.xml有问题
- 不要只看本项目中pom.xml的代码,要看该版本对应私服上的代码。