Maven父POM改为jar打包时如何获取各子模块版本并整合子构建产物
注意事项
不要直接修改原父POM A的packaging类型为jar,pom类型的父POM才是用来管理子模块、做依赖和插件继承的标准类型,强行修改会导致模块构建顺序异常、继承关系失效。建议新增一个专门的聚合打包子模块实现所有产物整合的需求,原父POM保留pom类型即可。
第一步:通用化子模块的shade插件配置
把三个子模块重复的shade插件配置移到父POM的pluginManagement节点中统一管理,即可实现所有子模块通用同一份配置,不需要在每个子POM里重复写全量代码。
针对你提到的manifestEntries通用化问题,可以直接用${project.artifactId}Version动态生成键名,每个子模块构建时会自动替换为自身的 artifactId 作为键,版本号取子模块自身的${project.version}:
<!-- 父POM的pluginManagement节点添加以下配置 --> <pluginManagement> <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> <finalName>${project.artifactId}</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <!-- 动态生成键名,比如B模块自动生成BVersion,C模块自动生成CVersion --> <${project.artifactId}Version>${project.version}</${project.artifactId}Version> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </pluginManagement>
调整后每个子模块的build节点可以简化为仅声明引用插件即可:
<!-- B、C、D子模块的build节点简化为以下内容 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> </plugin> </plugins> </build>
第二步:配置聚合打包模块整合所有子模块产物
在父POM的modules列表下新增一个专门的聚合打包模块(比如命名为all-in-one),在该模块的POM中添加B、C、D三个子模块为依赖,再配置shade插件合并所有产物即可。如果需要在最终整合包的manifest中写入所有子模块的版本号,直接引用父POM中统一管理的子模块版本属性即可:
<!-- 聚合打包模块all-in-one的POM配置 --> <dependencies> <dependency> <groupId>替换为你的项目groupId</groupId> <artifactId>B</artifactId> <version>${b.version}</version> </dependency> <dependency> <groupId>替换为你的项目groupId</groupId> <artifactId>C</artifactId> <version>${c.version}</version> </dependency> <dependency> <groupId>替换为你的项目groupId</groupId> <artifactId>D</artifactId> <version>${d.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <!-- 写入所有子模块的版本号 --> <BVersion>${b.version}</BVersion> <CVersion>${c.version}</CVersion> <DVersion>${d.version}</DVersion> </manifestEntries> </transformer> <!-- 保留spring配置文件合并逻辑 --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
子模块的版本可以统一在父POM的properties节点中定义b.version、c.version、d.version属性统一管理,所有模块都可以直接引用。
如果你一定要在原父POM中完成打包,把上述all-in-one模块的配置直接迁移到原父POM中,再把原父POM的packaging改成jar即可,构建时在根目录执行mvn install会先完成所有子模块构建,再生成父POM的整合jar包。
内容的提问来源于stack exchange,提问作者lulu3131

