踩坑背景:
最近在自己搭建Dubbo的SpringBoot项目中,采用了Maven聚合的技术,其中有一个子模块名为api,专门用于对外暴露自己提供的dubbo服务接口。我想这种项目结构方式,应该有很多程序员都有见过或者在使用。
目录结构如图:
dubbo-springboot-demo
|
|-- api (对外暴露的dubbo服务接口)
|-- web (前端页面及controller层)
|-- biz (业务逻辑层)
|-- dao (数据库操作层)
其中我的聚合pom(同时兼任父pom)里面依赖了SpringBoot2.x的parent依赖。
然后我对api模块进行mvn clean install,它也确实把jar包安装到我的本地仓库中。但是其他maven项目却无论如何都无法依赖。这个问题困扰了我一天,因为过于简单所以找不到原因,同时也由于一开始的问题定位不对,而导致浪费了时间。在我反应过来,这可能和maven聚合打包有关,在百度简单搜索了一下后马上就找到了答案。
以下开始解决这个坑:
在其他项目引入该依赖时,你会出现如下几种情况:
(1)pom中引入依赖,但是引不进来,还带波浪线
(2)没有波浪线了,但是你在导入包里面的类时却这样见红
解决方法:
(1)出现第一种情况,一般是因为你只mvn install了api模块。而没有为父pom打包,所以你api模块的pom里面的<parent>标签里面指向的父pom找不到,所以也就导致这个依赖也失效了。
(2)【重点】由于是Springboot项目,因此一般会携带这样一个plugin插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
它是罪魁祸首,你要做的就是不要在你的api模块的pom中引入该plugin。
我上述的项目中,由于在父pom中引入了spring-boot-maven-plugin,所以导致其所有子模块的pom中都继承了该plugin。
因此我的做法是:
- 父pom中不声明该plugin,在web,biz,dao中pom单独声明。然后api模块不声明
- 父pom依然声明该plugin,只不过在api模块的pom中打包时跳过该plugin
第二种方法的代码:(在api模块的pom.xml中)
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
综上所述:api模块一定不能有spring-boot-maven-plugin,否则其他项目就无法依赖它
原理简述:
spring-boot-maven-plugin这个插件会导致打包出来的jar不可被依赖
其实很好理解,SpringBoot项目打包出来的jar,一般都是直接运行。不会作为其他项目的依赖使用
最后这么一个简单的问题却卡了我一整天,只能怪自己以前没有去特别注意spring-boot-maven-plugin这个插件关于jar包不能被依赖这一点。
感谢这两位作者的文章,转载引用出处:
关于maven项目多模块的打包问题的血泪经历
maven父子工程–子模块相互依赖打包时所遇到的问题:依赖的程序包找不到
本来本人是不喜欢把别人写过的东西,自己再总结一遍作为原创发布的,但是我发现这两个标题可能都不太好让人定位问题,或者说,其实这个问题的出现并不是由于maven多模块技术,实际上就仅仅只是跟springboot的这个plugin有关,仅此而已。