Maven中同一插件两次执行中间能否插入运行其他插件?同阶段执行顺序问题
结论
通用场景下无法实现该需求:同一个构建阶段内,不能在同一个插件的两次执行中间插入其他插件的执行。
原因说明
- Maven内置POM合并规则:会自动将所有
groupId、artifactId完全一致的插件声明合并为同一个配置项,无论两次声明中间插入了多少其他插件的配置,同一个插件的所有<execution>执行配置都会被归集到同一条插件配置下。 - 同阶段执行顺序规则:
- 不同插件绑定到同一个阶段时,按插件在POM中首次声明的顺序依次执行
- 同一个插件的多个执行绑定到同一个阶段时,按执行ID的字典序(Maven 3.3.1之前版本)或声明顺序(Maven 3.3.1及之后版本)依次执行
你遇到的问题就是合并规则导致的:两次声明的maven-antrun-plugin被合并为一个,两个执行配置都归集到了maven-dependency-plugin之前的位置,最终执行顺序变为「复制项目jar→编译安装包→复制依赖」,和预期不符。
可行替代方案
方案1:绑定到不同的预置构建阶段
利用Maven默认生命周期的阶段先后顺序实现执行顺序控制,比如:
- 复制项目jar绑定到
prepare-package阶段 - 复制依赖绑定到
package阶段 - 编译安装包绑定到
pre-integration-test阶段
三个阶段默认按顺序执行,完全符合你的需求。
方案2:自定义生命周期阶段
如果不想改动默认阶段的绑定逻辑,可以自定义连续的三个生命周期阶段,按顺序绑定三个执行即可,对原有构建逻辑侵入最小。
方案3:整合执行逻辑
当前场景可以将复制依赖的逻辑改用Ant任务实现,全部放在同一个maven-antrun-plugin的多个按顺序执行的target中,也能保证执行顺序。
问题原始说明(已翻译)
为便于说明,假设需要完成以下操作:
- 复制项目构件jar(使用
maven-antrun-plugin) - 复制依赖(使用
maven-dependency-plugin) - 编译安装包(使用
maven-antrun-plugin)
但实际运行时两次maven-antrun-plugin的执行会被合并触发,同时会抛出插件重复声明的警告,两处声明会在有效POM中合并为一处。
补充说明:这个特定需求可以通过绑定到其他阶段或者使用install4j插件实现,但想了解通用场景下,是否可以在同一个构建阶段内按指定顺序多次执行maven-antrun-plugin这类插件,且两次执行中间插入其他插件的执行?
原始POM配置
<build> <plugins> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- 复制项目jar --> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>copy-project-jar</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <copy file="target/${project.artifactId}-${project.version}.jar" tofile="target/installer/bin/${project.artifactId}.jar" /> </target> </configuration> </execution> </executions> </plugin> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- 复制依赖 --> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/installer/bin</outputDirectory> <stripVersion>true</stripVersion> </configuration> </execution> </executions> </plugin> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- 编译安装包 --> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>compile-installer</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <exec executable="${install4j.home}/bin/install4jc.exe"> <arg value="installer.install4j" /> </exec> </target> </configuration> </execution> </executions> </plugin> </plugins> </build>
合并后的有效POM配置
<plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>copy-project-artifact</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <copy file="target/test-1.0.0.jar" tofile="target/installer/bin/test.jar" /> </target> </configuration> </execution> <execution> <id>compile-installer</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <exec executable="C:\Program Files\install4j8/bin/install4jc.exe"> <arg value="installer.install4j" /> </exec> </target> </configuration> </execution> </executions> </plugin>
内容的提问来源于stack exchange,提问作者Reto Höhener
相关产品推荐
相关产品推荐

