Maven - 根据属性激活子配置文件

28

场景:

  1. 已有
    1. 定义了一个配置文件和一个子模块的父POM
    2. 子项目将引用父POM中所定义的配置文件(通过继承方式)
  2. 目的是在父项目中跳过配置文件的执行,仅在子项目中执行
  3. 配置文件中有激活部分 <activation><property><name>foo</name></property><activation>
  4. 由于父项目没有定义 foo 属性 - 配置文件未被激活,不会在父项目构建时执行
  5. 现在,在子项目中定义 <properties><foo>true</foo></properties> ,期望在子项目构建时该属性将被使用并激活配置文件。但结果却不如愿以偿,配置文件从未被激活,这说明该属性从未被设置。
  6. 请注意:mvn package -Dfoo=true 会同时在父项目和子项目中激活该配置文件

我是在尝试不可能的事情还是方法错误了?

P.S. 嗯- 即使我在父项目中定义了属性,也无法触发配置文件。这是怎么回事?

3个回答

10

在@rich-seller的答案和@Bostone的自答的基础上,似乎不可能设置父POM定义几个替代配置文件,而子POM默认选择其中一个配置文件,并允许您临时覆盖子项的选择(即在CLI上)。 考虑一个用于项目使用某种框架和关联插件的父POM,我们可以假定这些版本都由属性定义:

<profiles>
  <profile>
    <id>newest</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <framework.version>2.0</framework.version>
      <plugin.version>2.0</plugin.version>
    </properties>
  </profile>
  <profile>
    <id>older</id>
    <activation>
      <property>
        <name>older.framework</name>
        <value>true</value>
      </property>
    </activation>
    <properties>
      <framework.version>1.1</framework.version>
      <plugin.version>1.1</plugin.version>
    </properties>
  </profile>
</profiles>

现在,一个从这个父POM继承的子模块默认会使用2.0,就像你所期望的那样,-Polder-Dolder.framework=true可以用来尝试使用旧框架进行构建(例如测试兼容性)。然而,在子模块的POM文件中你不能进行编写。

<properties>
  <older.framework>true</older.framework>
</properties>

可以通过将配置信息复制到子POM中实现自动激活older配置文件。如果newest不是默认激活的,您可以使用基于文件的激活来使此模块构建针对1.1版本,但是这样就不容易暂时将其运行针对2.0版本:据我所知,如果您传递-Pnewest,则两个oldernewest配置文件都将处于活动状态,因此您需要明确地禁用其他配置文件,如果您有十几个配置文件,则这是不合理的。因此,除了将配置信息复制到子POM中,没有其他解决方案:

<properties>
  <framework.version>1.1</framework.version>
  <plugin.version>1.1</plugin.version>
</properties>

这时候使用-Pnewest将无法覆盖这些属性,所以你需要使用-Dframework.version=2.0 -Dplugin.version=2.0

换句话说,只有当所有子模块默认都能使用相同的配置文件(此处为newest)时,配置文件才有用。如果其中一些子模块通常使用1.1版本,而其他的则使用2.0版本,则配置文件就没用了。

似乎这是Maven核心增强或Maven 3构建扩展的用例。http://docs.codehaus.org/display/MAVEN/Custom+Profile+Activatorshttps://github.com/maoo/maven-tiles看起来不错。


是的,我接受这个答案,因为它基于我的回答,并且我通常不喜欢接受自己的答案。 - Bostone
非常有用的信息。感谢您提供关于基于文件激活的提示;这非常干净地解决了我的问题。 - Allan

7

只有通过从命令行传递的属性才能激活配置文件。这是因为POM中的属性只能在解析POM后处理一次,此时已经太晚解决配置文件的激活。

如果您无法从命令行传递属性、在settings.xml中指定配置文件激活(通常不是一个好主意)或使用我的以前的答案中的解决方法来使用标记文件的存在,则会遇到一些困难。

最后一个选择是,如果您正在使用Maven 2.1.0+,则仅通过命令行为父POM 停用配置文件,但这显然仍然不理想。

您可以使用字符“!”或“-”来停用配置文件,如下所示:

mvn install -P !profile-1,!profile-2

我很担心。实际上,似乎在启动构建后(即使使用标记文件),配置文件的执行设置是固定的,无法更改。如果我停用了,那么这些“-1”和“-2”是指什么?如果我有父级和子级以及配置文件“build”,那么以下内容是否应该取消父级上的配置文件?(在我的测试中,它没有)mvn install -P !buiild-1 - Bostone
我不是很理解。为什么 <missing> 或者 <exists> 的配置文件触发器对你没有用呢? - Pascal Thivent
例子是停用名为 profile-1profile-2 的两个配置文件,-1-2 没有特殊意义。在您的情况下,它将简单地是 mvn install -P !build - Rich Seller
但这将停用整个配置文件,既不会在父级上执行,也不会在子级上执行?或者我漏掉了什么? - Bostone
我无法让它与文件一起工作。与属性相同的行为。请原谅一个愚蠢的问题,您是否实际运行并验证了它是否正常工作?我很想看到那段代码。 - Bostone
显示剩余5条评论

7
直接回答我的问题:在多模块构建中,所有属性都在运行构建之前设置,因此不可能根据在子POM中设置属性来在一个模块中“在构建期间”激活/停用配置文件。但是,如果您正在寻找通过其他方式实现它的方法,请阅读此评论

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