为啥我不能从另一个配置文件激活 Maven2 配置文件?

Posted

技术标签:

【中文标题】为啥我不能从另一个配置文件激活 Maven2 配置文件?【英文标题】:Why can't I activate a Maven2 profile from another profile?为什么我不能从另一个配置文件激活 Maven2 配置文件? 【发布时间】:2011-01-15 19:19:36 【问题描述】:

我有一个构建 Web 应用程序的多模块 Maven2 项目。该应用程序连接到后端服务器和数据库。我们的环境中部署了多个服务器实例,也有多个后端和数据库实例用于开发、UAT、生产等。所以实际上,每个应用程序配置都需要这3个坐标:

前端服务器 后端服务器 数据库

我正在努力统一和自动化应用程序配置。在 Maven 中将这些不同的配置表示为配置文件很容易且显而易见。然后我可以通过激活每个组中的一个配置文件来创建特定配置,例如

mvn -Pserver.Server1,backend.prod,db.uat clean install

这有点繁琐且容易出错 - 如果特定服务器配置错误以连接到错误的数据库,则价格可能会很高。解决此问题的一种明显方法是将所有有用的配置文件组合放入脚本文件中。

但我认为我可以比直接从服务器配置文件激活必要的后端和数据库配置文件更聪明。服务器配置文件位于主 pom 中,例如

<profile>
    <id>server.myserver</id>
    <properties>
        <jboss.home>D:\Programs\jboss-4.2.1.GA</jboss.home>
        <server.name>NightlyBuild</server.name>
        <hosttobind>192.168.1.100</hosttobind>
        <servlet.port>8080</servlet.port>
        ...
        <db>dev02</db>
    </properties>
</profile>

并且后端和数据库配置文件在 Config 子模块的 pom 中,例如

<profile>
    <id>db.dev02</id>
    <activation>
        <property>
            <name>db</name>
            <value>dev02</value>
        </property>
    </activation>
    <properties>
        <jdbc.address>jdbc:oracle:thin:@192.168.0.101:1521:dbdev02</jdbc.address>
    </properties>
</profile>

所以理论上,由于server.myserver 配置文件将db 属性设置为dev02,这应该会触发子pom 中db.dev02 配置文件的激活。但是,这不会发生。 (如果这两个配置文件在同一个 pom 中,顺便说一句)。如果我使用

从命令行设置属性
mvn -Ddb=dev02 help:active-profiles

然后配置文件被激活,所以显然我没有拼错任何东西。

我是否忽略了什么?有没有其他方法可以完成这项工作?

我看到有一个类似的问题:Can I make one maven profile activate another? 但是,恕我直言,这不是重复的-我看到我的方法不起作用,我想了解原因。 (我已经阅读了参考资料,但我可能忽略了一些明显的东西)。

【问题讨论】:

【参考方案1】:

该功能根本不存在。属性激活器使用传入的属性,而不是配置文件设置的任何内容(否则它不会知道在没有一些更复杂的逻辑的情况下激活它们的顺序)。

您使用的解决方案,具有相同的属性来激活您想要一起做的事情,是最好的解决方案。我意识到这可能并不总是令人满意 - 在这种情况下,您所能做的就是让各个配置文件尽可能简单,以便您可以在命令行上以您想要的方式组合它们,而不会在它们之间重复。

涉及此功能的问题是:https://issues.apache.org/jira/browse/MNG-3309 涉及属性激活的问题是:https://issues.apache.org/jira/browse/MNG-2276

【讨论】:

@Brett,谢谢,这解决了问题。然而,最后一件事:你写了“你使用的解决方案,具有相同的属性来激活你想要一起做的事情,是最好的解决方案。”。凭什么?美学上可能,但它仍然不起作用...... 我的意思是“从命令行”。因此,如果您需要profile1 来暗示profile2 被激活,请确保它们都被propertyX 激活,然后使用mvn -DpropertyX 而不是mvn -Pprofile1。但它并不像您想要的那样灵活。【参考方案2】:

Brett 提到的Issue MNG-2276 已在 maven 3.x 中解决,因此您现在可以在 settings.xml 中定义属性以触发 pom 中的配置文件。这是一个例子:

在settings.xml中:

<profile>
    <id>localDist</id>
    <activation>
        <property><name>localDist</name></property>
    </activation>
    <properties>
        <doReleaseTasks>true</doReleaseTasks>
    </properties>
</profile>

在你的 pom 中(或者更好的是,在你的父 pom 中):

<profile>
    <id>doReleaseTasks</id>
    <activation>
        <property><name>doReleaseTasks</name></property>
    </activation>
    <build>
        <plugins>
            ... mvn -DlocalDist will activate these plugins
        </plugins>
    </build>
</profile>

使用强制插件强制 mvn 3.0 或更高版本的好主意:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-enforcer-plugin</artifactId>
            <executions>
                <execution>
                    <id>enforce-maven</id>
                    <goals> <goal>enforce</goal> </goals>
                    <configuration>
                        <rules>
                            <requireMavenVersion>
                                <version>[3.0,)</version>
                                <message>
*** Maven 3.x required to allow cascading profiles to be activated in settings.xml (MNG-2276)
                                </message>
                            </requireMavenVersion>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

【讨论】:

以上是关于为啥我不能从另一个配置文件激活 Maven2 配置文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥从另一个调用的函数不会显示在节点应用程序的配置文件输出中?

为啥我不能在汇总配置文件中使用 ES6 导入/导出?

为啥 environment.getProperty("spring.profiles.active") 在使用 @ActiveProfiles 激活测试中的配置文件时返回 nul

为啥我不能从另一个控制器中删除视图?

Maven2的配置文件settings.xml

为啥我不能使用 MobileFirst 命令行工具添加合适的服务器配置文件?