PAYATHON 2026

如何根据另一个 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,确认实际版本。级联激活说明

备注:内容仅供参考。