如何根据另一个 profile 中设置的 property 激活公共 profile?
结论
在问题使用的 Maven 3 中,一个 POM profile 设置的属性不能用来激活另一个 profile。-Parq-glassfish-managed 可以把 skip.integration.tests 改为 false,供 Failsafe 使用,但不会自动激活 arq-common-deps。
最直接的做法是同时指定两个 profile:
mvn verify -Parq-glassfish-managed,arq-common-deps
也可以为公共 profile 配置相应的 <activation> 条件,再从命令行传入属性来激活它:
mvn verify -Parq-glassfish-managed -Dskip.integration.tests=false
为什么 profile 中的属性不能触发另一个 profile
Maven 3 构建项目模型时,会先判断哪些 profile 需要激活,再将已激活 profile 的内容合并到模型中,随后进行属性插值。因此,arq-glassfish-managed 中定义的属性无法参与此前已经完成的 profile 激活判断。调整两个 profile 的声明顺序也无法解决这个问题。Maven 3 模型构建顺序
同一个属性在这两处的用法不同:
- Failsafe 配置中的
${skip.integration.tests}可以读取已激活 profile 提供的值。 - 用于激活 profile 的
<activation><property>不能依赖另一个 POM profile 稍后提供的值,但可以使用命令行传入的-D属性。
原配置还有两处 XML 错误:</properities> 应改为 </properties>;用于激活的 <property> 必须放在 <activation> 内,不能直接放在 <profile> 下。
方案一:显式激活两个 profile
在容器 profile 中保留测试开关,让公共 profile 只负责公共依赖。将以下片段合并到现有 pom.xml 的 <project> 下:
<properties>
<skip.integration.tests>true</skip.integration.tests>
</properties>
<profiles>
<profile>
<id>arq-common-deps</id>
<dependencies>
<!-- 保留项目实际使用的 Arquillian 公共测试依赖 -->
</dependencies>
</profile>
<profile>
<id>arq-glassfish-managed</id>
<properties>
<skip.integration.tests>false</skip.integration.tests>
</properties>
<!-- 保留 GlassFish managed 的依赖和配置 -->
</profile>
</profiles>
运行:
mvn verify -Parq-glassfish-managed,arq-common-deps
-P 支持用逗号分隔多个 profile。这样,公共依赖和容器配置都会参与构建,无需让一个 profile 触发另一个。Maven profile 指南
方案二:从命令行提供激活属性
如果希望启用集成测试时自动加入公共依赖,可以把公共 profile 改为:
<profile>
<id>arq-common-deps</id>
<activation>
<property>
<name>skip.integration.tests</name>
<value>false</value>
</property>
</activation>
<dependencies>
<!-- 保留项目实际使用的 Arquillian 公共测试依赖 -->
</dependencies>
</profile>
然后执行:
mvn verify -Parq-glassfish-managed -Dskip.integration.tests=false
-P 选择 GlassFish 容器配置,-Dskip.integration.tests=false 则满足公共 profile 的激活条件,同时为 Failsafe 提供测试开关值。激活条件中的 <name> 直接填写属性名,不要写成 ${skip.integration.tests}。属性激活规则
在 Maven 3 中,如果只执行下面的命令,公共 profile 仍不会被容器 profile 中的同名属性激活:
mvn verify -Parq-glassfish-managed
确保 Failsafe 使用了这个开关
skip.integration.tests 是项目自定义属性,Failsafe 不会自动识别这个名称,需要将它显式绑定到插件的 skipITs 参数:
<skipITs>${skip.integration.tests}</skipITs>
可以将以下配置合并到现有的 <build><plugins> 中,保留项目已确定的插件版本。如果版本由父 POM 的 pluginManagement 管理,可以沿用:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipITs>${skip.integration.tests}</skipITs>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
skipITs=false 表示允许执行集成测试。测试仍需符合项目配置的发现规则,并具备所需的 Arquillian 依赖和容器配置。使用 mvn verify 可以执行到 Failsafe 的测试结果检查阶段。Failsafe 跳过测试配置、Failsafe 使用说明
检查配置与版本边界
使用与实际构建相同的参数,查看已激活的 profile 和最终 POM:
mvn help:active-profiles -Parq-glassfish-managed -Dskip.integration.tests=false
mvn help:effective-pom -Parq-glassfish-managed -Dskip.integration.tests=false
确认两个 profile 都已激活,公共依赖和 Failsafe 的 skipITs 配置也已进入最终模型。Maven Help Plugin 使用说明
如果在 Maven 3 中必须只传入 -Parq-glassfish-managed,可以将公共测试依赖移到项目级 <dependencies>,使用 test scope。不过,这些依赖也会在其他构建中可用。另一种做法是在各容器 profile 中分别声明所需依赖。
上述限制针对 Maven 3。Maven 官方指南注明,从 Maven 4.1 起,支持通过 profile 属性触发其他 POM profile 的“级联激活”。使用前应先运行 mvn -v,确认实际版本。级联激活说明
备注:内容仅供参考。
