【必看防踩坑】关于SpringBoot的Maven多模块的子模块打包问题

踩坑背景:

最近在自己搭建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。

因此我的做法是

  1. 父pom中不声明该plugin,在web,biz,dao中pom单独声明。然后api模块不声明
  2. 父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有关,仅此而已。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用 Maven 进行 springboot模块单元测试和 Jacoco 代码覆盖率统计。 对于多模块项目,需要在父 POM 文件中添加 Jacoco 插件配置,以及指定模块的测试目录: ```xml <modules> <module>module1</module> <module>module2</module> <module>module3</module> </modules> <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report-aggregate</id> <phase>test</phase> <goals> <goal>report-aggregate</goal> </goals> </execution> </executions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>unit-test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skipTests>false</skipTests> <skip>false</skip> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <argLine>${jacoco.agent.argLine}</argLine> <excludedGroups>org.junit.experimental.categories.ExcludeCategory</excludedGroups> <testFailureIgnore>true</testFailureIgnore> <includes> <include>**/*Test.java</include> </includes> </configuration> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </profile> </profiles> <modules> <module>module1</module> <module>module2</module> <module>module3</module> </modules> <profiles> <profile> <id>unit-test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skipTests>false</skipTests> <skip>false</skip> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <argLine>${jacoco.agent.argLine}</argLine> <excludedGroups>org.junit.experimental.categories.ExcludeCategory</excludedGroups> <testFailureIgnore>true</testFailureIgnore> <includes> <include>**/*Test.java</include> </includes> </configuration> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </profile> </profiles> ``` 这个配置会在编译和测试时启动 Jacoco 代理,同时在测试后生成 Jacoco 报告。 同时,可以使用 Maven Profiles 来区分测试和生产环境的配置,例如上面的配置中就定义了一个名为 `unit-test` 的 Profile。在执行单元测试时,可以使用命令 `mvn clean test -Punit-test` 来指定使用 `unit-test` Profile。 对于单个模块的项目,可以在模块的 POM 文件中添加 Jacoco 插件配置: ```xml <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> ``` 这个配置会在编译和测试时启动 Jacoco 代理,同时在测试后生成 Jacoco 报告。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值