如何保持Maven中默认激活的配置文件在其他配置文件被激活时仍然处于激活状态?

143

我在pom.xml中有一个配置文件,它应该始终处于活动状态,除非明确禁用(-P !firstProfile)。 我通过使用activeByDefault标志来解决这个问题:

<profiles>
  <profile>
    <id>firstProfile</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    ...
  </profile>
</profiles>

现在在同一个pom.xml文件中,我定义了第二个配置文件,只有在真正激活(-P secondProfile)配置文件时才会激活它。因此,默认行为是:第一个配置文件处于活动状态,第二个配置文件处于非活动状态。 在某些时候,我希望除了第一个配置文件之外,还能同时激活第二个配置文件。 现在的问题是,如果我使用"-P secondProfile"这个命令来实现,不幸的是,第一个配置文件将被停用。 Maven文档如下所述:

... 该配置文件在所有构建中自动激活,除非通过先前描述的一种方法激活POM中的另一个配置文件。默认情况下激活的所有配置文件在通过命令行或其激活配置激活POM中的配置文件时都会自动停用。 ...

是否有办法始终保持第一个配置文件处于活动状态(而不必在settings.xml中声明)?


7个回答

178

一个技巧是避免使用activeByDefault,而是通过属性的不存在来激活配置文件,例如:

<profiles>
  <profile>
    <id>firstProfile</id>
    <activation>
      <property>
        <name>!skipFirstProfile</name>
      </property>
    </activation>
    ...
  </profile>
</profiles>

你可以使用-DskipFirstProfile-P !firstProfile来停用该配置文件,否则该配置文件将会生效。

详见:Maven: The Complete Reference, Profile Activation - Activation by the Absence of a Property


在什么情况下,这种方式比显式地提及配置文件本身更有帮助或更好?例如,我可以使用-PmyDefaultProfile而不是传递-DmyFlag。是否有通过标志控制它的好处我没有注意到的? - Chetya
4
只有当标志不存在时,配置文件才会自动激活。只有在指定了-DskipFirstProfile(例如 mvn verify -DskipFirstProfile)时,配置文件firstProfile才会被禁用。请注意,本句中的“禁用”即为“disabled”。 - seanf

30
我希望有这样的可能性,我经常错过它。我找到的唯一相关的JIRA问题是这个: MNG-4917:即使将activeByDefault设置为true,配置文件仍未激活 它已被解决为“不是问题”。
我已停止使用activeByDefault,因为这种“全有或全无”的方法对我毫无价值。

改变这种行为的唯一方法是编写自己的DefaultProfileSelector替代品,使用@Component(role=ProfileSelector.class)将其注册为Plexus组件,并将其放置在${MAVEN_HOME}/lib/ext中(这样它将被选为默认配置文件选择器)。 (如果您使用的是Maven 3.0.2或更早版本,还必须编辑${MAVEN_HOME}/bin/m2.conf以在加载lib之前加载lib/ext


另一个不错的选择是配置文件继承或配置文件装饰器,允许基本配置被重复使用。 - crowne
@crowne 当然可以,为什么不将其建议为功能请求呢? - Sean Patrick Floyd
这有点相关... 我喜欢将所有模块添加到默认情况下的活动档案中,因为我认为没有办法从执行中删除模块。 在3.2.1中,他们添加了此功能,如此处所示。 如果有人和我一样正在使用模块,则我将保留此评论以防万一。 - Captain Man

12

这个问题很古老,但似乎可以通过使用activeProfile而不是activeByDefault来解决。我使用的是Maven 3.3.9,但该解决方案可能在早期版本上也适用。

只需在settings.xml中列出您的activeProfiles,就像这样:

<settings>
  <profiles>
    [...]
  </profiles>
  <activeProfiles>
    <activeProfile>my-awesome-profile</activeProfile>
  </activeProfiles>
</settings>

my-awesome-profile中,我有像数据库URL等设置,因此它们始终适用。在这里,我激活了第二个配置文件resolve-from-central

$ mvn help:all-profiles -P resolve-from-central 
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-help-plugin:2.2:all-profiles (default-cli) @ standalone-pom ---
[INFO] Listing Profiles for Project: org.apache.maven:standalone-pom:pom:1
  Profile Id: resolve-from-central (Active: true , Source: settings.xml)
  Profile Id: my-awesome-profile (Active: true , Source: settings.xml)
  Profile Id: resolve-from-internal (Active: false , Source: settings.xml)

注意看,my-awesome-profile 仍然是活动的。耶!


2
在工作环境中,这不是一个好的解决方案,因为其他开发人员可能没有包含此设置的settings.xml文件,从而导致不同的构建行为。 - Geert Schuring
我相信你有些困惑,@GeertSchuring。在工作环境中,这是一个很好的解决方案,因为你正在更改个人的settings.xml文件而不是共享的pom.xml - inanutshellus
4
OP明确要求不涉及settings.xml的解决方案... - Geert Schuring
如果您无法通过其他解决方案更改pom.xml文件,也无法更改个人settings.xml文件,则我怀疑您陷入了“黄金锤”情况,并需要重新评估您正在尝试做什么。 - inanutshellus

8

个人配置文件是将POM有序化的好方法。尤其是当您使用相同插件的多个执行目的不同时。

使用文件:

<profile>
    <id>alwaysActive</id>
    <activation>
         <file><exists>.</exists></file>
    </activation>
    ...
</profile>

这将始终为真(除非在Maven启动期间有人删除了目录:)。在Maven 3.6.0版本中进行了测试。

这也可能是区分项目类型的好方法。例如,我的项目总是存在 module.json

使用配置文件激活扩展

有一些用于配置文件激活的Maven扩展程序。其中一个可以在此处找到:
https://github.com/OndraZizka/el-profile-activator-extension


1
小修正,似乎应该是 <file><exists>.</exists></file> - revau.lt

4
您可以在命令行上简单列出所有要激活的配置文件,如下所示:
-P profile-1,profile-2
Maven旨在自动允许多个配置文件激活,但如果您使用-P覆盖它,则只会激活参数中列出的配置文件。

7
这并非完全正确。仅使用“-P”手动激活配置文件只会停用“<activeByDefault>”配置文件。在“settings.xml”中通过“<activeProfiles>”或任何其他类型的“<activation>”激活的配置文件,除非明确停用,否则将保持激活状态。 - Sam Hanes

0
这是我对activeByDefault的解决方法,这个设计本身就有问题,详见MNG-4917。感谢Sean Patrick Floyd在他的回答中提供了那个问题的链接。
<activation>
  <jdk>[1.)</jdk>
</activation>

0
你不能保持默认配置文件处于活动状态,但可以将该配置文件的内容(例如中的...)移至pom文件的主要部分。
仅仅因为你在使用配置文件,并不意味着你所有的操作都需要在配置文件内完成。

1
这并没有回答问题 - OP明确指出配置文件应该是“始终处于活动状态,除非明确停用”。可能有时需要明确禁用它,而这个答案不允许。 - sleske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接