Maven中的继承配置文件

时间:2013-09-18 09:38:40

标签: maven maven-profiles

我的父pom中有以下个人资料

<profile>
    <id>P1</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>

<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
</profile>

为什么P1在子POM中处于活动状态而P2不在?

目录${project.basedir}/src/main/whatever在父项目中不存在,但存在于子项目中。

5 个答案:

答案 0 :(得分:16)

配置文件P2未激活,因为即使目录exists存在,其${project.basedir}/src/main/whatever标记下的路径也无法解析为现有路径。如果您将属性${project.basedir}重写为${basedir},则应激活P2个人资料。

这应该意味着${project.basedir}不会像should那样解析到项目基目录。但help:effective-pom显示它确实如此。我已经报告了这个(MNG-5516)。

  

另外我认为如果P2是P1,P1将不会被激活。

这是正确的。引用documentation for activeByDefault

  

除非使用上述方法之一激活同一POM中的另一个配置文件,否则此配置文件(本例中为P1)将自动为所有版本激活。默认情况下处于活动状态的所有配置文件在命令行上激活POM中的配置文件或通过其激活配置时自动停用。

单词 inherit 让我感到困惑,因为“个人资料继承”适用于project aggregation但不适用于project inheritance

为了清楚起见,我模拟了这种情况。 空pom 表示除了标准型号,组,工件和版本标签外它是空的。

简单场景

目录结构:

simple
 \-pom.xml

pom内容:

<profiles>
    <profile>
        <id>P1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>P2</id>
        <activation>
            <file>
                <exists>${basedir}/dir/</exists>
            </file>
        </activation>
    </profile>
</profiles>

如果没有dir目录mvn help:all-profiles输出:

Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

如果dir目录mvn help:all-profiles输出:

Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)

项目继承

目录结构:

inheritance
 |--child
 |  \-pom.xml         // child pom
 \-pom.xml           // parent pom

子pom为空,而父pom具有简单方案中的配置文件。无论来自inheritance/child/dir目录输出的mvn help:all-profiles目录是否存在child

Profile Id: P1 (Active: false , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

mvn help:effective-pom目录运行child时,表明配置文件确实没有被继承。它表现为documented

  

POM中合并的元素如下:

     
      
  • 依赖关系
  •   
  • 开发人员和贡献者
  •   
  • 插件列表(包括报告)
  •   
  • 带有匹配ID的插件执行
  •   
  • 插件配置
  •   
  • 资源
  •   

此处未提及任何档案。

项目聚合

目录结构:

aggregation
 |--module
 |  \-pom.xml         // module pom
 \-pom.xml           // aggregator pom

模块pom为空,而聚合器pom具有简单方案中的配置文件。如果aggregation/module/dir目录输出中没有mvn help:all-profiles目录正在运行module

Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)

如果从aggregation/module/dir目录输出中有mvn help:all-profiles目录正在运行module

Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)

mvn help:effective-pom目录运行module时,它会显示配置文件是继承的。这不是explicitly documented

项目继承

  

如果你有几个Maven项目,并且它们都有类似的配置,你可以通过拉出那些类似的配置并制作一个父项目来重构你的项目。因此,您所要做的就是让您的Maven项目继承该父项目,然后将这些配置应用于所有这些项目。

注意:

  • 这不适用于配置文件,因为它已经显示出来。
  • inheritance目录运行maven版本将只运行父版本。

项目汇总

  

如果您有一组一起构建或处理的项目,您可以创建一个父项目并让该父项目将这些项目声明为其模块。通过这样做,您只需要构建父级,其余的将跟随。

注意:

  • aggregation目录运行maven构建将运行每个模块和聚合器的构建(实际的顺序由maven根据不同的标准确定)。

结论

全局,每个用户或每个项目的个人资料可以是defined。由于聚合项目是一起构建的(在同一构建中),因此必须运行某种配置文件解析来计算活动项目。所以这是令人困惑的部分:

  • 当项目被继承时, 不是 从父pom继承到子pom
  • 当项目聚合时, 从聚合器pom继承到模块pom

使用Maven 3.1.0对此进行了测试。和3.0.5。

答案 1 :(得分:10)

为了澄清这一点,Maven Profiles实际上是继承的。有关另一个SO问题的参考,请参阅:Inheriting Maven profiles。我已成功在项目中继承了配置文件,无需其他工作。

对于原始问题,您在exists元素中定义了一个变量。根据{{​​3}}:

  

从Maven 2.0.9开始,标签就可以了   插值。支持的变量是系统属性,如   $ {user.home}和环境变量,如$ {env.HOME}。请注意   POM本身定义的属性和值不可用   用于插值,例如,以上示例激活器无法使用   $ {project.build.directory}但需要对路径目标进行硬编码。

所以,我得到的是$ {project.basedir}无法使用,也无法使用。但是,如果将它定义为环境变量,它将起作用。

我发现一个警告是父母pom documentation。但是,对于配置文件,我发现不能使用<plugin-management>以使特定于配置文件的配置起作用。

答案 2 :(得分:4)

问题不在于继承,而在于插值(即${...}支持哪些值):基于文件的配置文件激活仅支持有限插值:见http://maven.apache.org/pom.html#Activation

因此不支持${project.basedir},只支持${basedir}(和系统属性)。

有关详细信息,您可以查看模型构建算法:http://maven.apache.org/ref/3.2.1/maven-model-builder/

完整模型插值在配置文件激活后发生:因此,即使您的有效pom显示${project.basedir}的插值,也不会在配置文件激活时计算该值。

在Maven 3.2.2中,有多项增强功能:http://jira.codehaus.org/browse/MNG-5590中的文档,http://jira.codehaus.org/browse/MNG-5608中的运行时警告以及更有效的pom结果http://jira.codehaus.org/browse/MNG-5612

答案 3 :(得分:1)

通常,Maven配置文件不会被继承(请参阅http://jira.codehaus.org/browse/MNG-5127进行讨论并链接到可能有用的博客文章)。我成功做了这样的事情:

<!-- Parent -->
<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
    <!-- all the things you want to define for the child POMs -->
</profile>

<!-- Child -->
<!-- Include only the activation block, which must match parent's exactly -->
<!-- Whatever is in the parent will be inherited -->
<profile>
    <id>P2</id>
    <activation>
        <file>
            <exists>${project.basedir}/src/main/whatever</exists>
        </file>
    </activation>
</profile>

另外我认为如果P2是P1,P1将不会被激活。这是因为<activeByDefault>对于P1是正确的。在我看来,元素名称有点误导。 “默认为活动”意味着“始终处于活动状态”,当它真正意味着“只有在此POM中没有其他配置文件处于活动状态时才有效”。

以上使用Maven 3.0.x发现。

答案 4 :(得分:0)

从具有基于文件激活的第二个配置文件中删除P2。

<profiles>
    <profile>
        <id>P1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>P2</id>
        <activation>
            <file>
                <exists>${basedir}/dir/</exists>
            </file>
        </activation>
    </profile>
</profiles>