如何跨模块同步Maven构建生命周期阶段?
我有一个包含Maven反应堆(reactor)的项目,下设多个模块,多数模块打包为WAR包。模块在根pom.xml中的声明顺序决定了构建顺序:
.... <module>library1</module> <module>library2</module> <module>webapp1</module><!--war--> <module>webapp2</module><!--war--> <module>blackduck-scan</module><!-- create file to be placed into webapp2 post-build but pre-packaging of webapp2 --> ...
最后一个模块blackduck-scan用于在prepare-package阶段执行Black Duck许可证扫描工具,生成许可证通知文件,需放入webapp2的/webapp目录,以便部署后展示。核心需求是:该文件需在所有应用编译完成后、webapp2的WAR打包前注入,避免为重新打包而重复构建。
相关插件配置如下:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <configuration> <executable>java</executable> <workingDirectory>.</workingDirectory> <arguments> <argument>-jar</argument> <argument>synopsys-detect-8.4.0.jar</argument> </arguments> ... </configuration> <executions> <execution> <goals> <goal>exec</goal> </goals> <phase>prepare-package</phase> </execution> </executions> </plugin>
尝试过的方案均未达到预期:
- a) 在根
pom.xml中添加该插件:会在prepare-package阶段提前执行,此时项目未完全构建,扫描结果不完整; - b) 将插件作为独立模块:执行时机在所有模块构建末尾,但此时webapp2已完成打包,无法注入文件;
- c) 分两次调用Maven命令
mvn clean install && mvn package:可实现需求,但操作不够优雅。
已知模块按声明顺序构建,请问是否存在方法同步构建生命周期阶段,仅需执行mvn clean install即可完成全部流程?
方案1:将扫描逻辑整合到webapp2模块(推荐)
直接把Black Duck扫描插件配置到webapp2模块的pom.xml中,利用Maven反应堆的构建顺序,确保扫描在webapp2打包前执行,且所有依赖模块已构建完成:
- 移除独立的
blackduck-scan模块(可选,若不需要保留独立模块)。 - 在webapp2的
pom.xml中添加插件配置:<build> <plugins> <!-- 保留原有的WAR打包插件配置 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <configuration> <webResources> <resource> <directory>src/main/webapp</directory> <filtering>false</filtering> </resource> </webResources> </configuration> </plugin> <!-- Black Duck扫描插件 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <configuration> <executable>java</executable> <!-- 设置工作目录为项目根目录,确保扫描整个反应堆的依赖 --> <workingDirectory>${project.parent.basedir}</workingDirectory> <arguments> <argument>-jar</argument> <argument>${project.parent.basedir}/synopsys-detect-8.4.0.jar</argument> <!-- 指定输出目录到webapp2的webapp目录 --> <argument>--detect.output.path=${project.basedir}/target/webapp</argument> <!-- 其他扫描参数 --> </arguments> </configuration> <executions> <execution> <id>blackduck-scan</id> <goals> <goal>exec</goal> </goals> <!-- 绑定到webapp2的prepare-package阶段,此时所有前置模块已构建完成 --> <phase>prepare-package</phase> </execution> </executions> </plugin> </plugins> </build> - 执行构建命令:直接运行
mvn clean install即可。此时Maven会按顺序构建library1、library2、webapp1,然后构建webapp2:- 先完成webapp2的编译、测试等前置阶段;
- 在
prepare-package阶段执行Black Duck扫描,生成文件到webapp2的target/webapp目录; - 最后执行
package阶段,将文件打包进WAR包。
方案2:保留blackduck-scan模块,通过依赖控制执行时机
如果必须保留独立的blackduck-scan模块,可通过模块依赖调整构建顺序与阶段:
修改
blackduck-scan模块的pom.xml:- 添加对所有需要扫描的模块的依赖(确保这些模块先构建):
<dependencies> <dependency> <groupId>your.group.id</groupId> <artifactId>library1</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>your.group.id</groupId> <artifactId>library2</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>your.group.id</groupId> <artifactId>webapp1</artifactId> <version>${project.version}</version> <scope>compile</scope> <type>war</type> </dependency> <dependency> <groupId>your.group.id</groupId> <artifactId>webapp2</artifactId> <version>${project.version}</version> <scope>compile</scope> <type>war</type> </dependency> </dependencies> - 调整扫描插件的输出目录为webapp2的
target/webapp:<configuration> <executable>java</executable> <workingDirectory>${project.parent.basedir}</workingDirectory> <arguments> <argument>-jar</argument> <argument>synopsys-detect-8.4.0.jar</argument> <argument>--detect.output.path=${project.parent.basedir}/webapp2/target/webapp</argument> </arguments> </configuration>
- 添加对所有需要扫描的模块的依赖(确保这些模块先构建):
修改
webapp2模块的pom.xml:- 添加对
blackduck-scan模块的依赖,并调整WAR打包阶段:<dependencies> <dependency> <groupId>your.group.id</groupId> <artifactId>blackduck-scan</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <executions> <execution> <id>default-war</id> <!-- 将WAR打包阶段延迟到verify阶段,确保扫描文件已生成 --> <phase>verify</phase> </execution> </executions> </plugin> </plugins> </build>
- 添加对
调整根pom.xml的模块顺序:将
blackduck-scan模块移到webapp2之前,确保扫描在webapp2的verify阶段前完成:<modules> <module>library1</module> <module>library2</module> <module>webapp1</module> <module>blackduck-scan</module> <module>webapp2</module> </modules>执行构建命令:运行
mvn clean install,Maven会按顺序构建所有前置模块→blackduck-scan(执行扫描并复制文件到webapp2的target)→webapp2(执行verify阶段打包WAR)。
内容的提问来源于stack exchange,提问作者jenszo

