Maven中继承的配置文件

0md85ypi  于 12个月前  发布在  Maven
关注(0)|答案(5)|浏览(235)

我有以下配置文件在我的父母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在父项目中不存在,但在子项目中存在。

flmtquvp

flmtquvp1#

配置文件P2未激活,因为即使目录${project.basedir}/src/main/whatever存在,其exists标记下的路径也无法解析为现有路径。如果将属性${project.basedir}重写为${basedir},则应激活P2配置文件。
这应该意味着${project.basedir}没有像它应该的那样解析到项目基目录。help:effective-pom显示它确实如此。我已经报告了这一点(MNG-5516)。
我也认为如果P2活跃,P1就不会活跃。
没错引用documentation for activeByDefault的话
此配置文件(本示例中为P1)将自动为所有生成激活,除非使用上述方法之一激活同一POM中的另一个配置文件。当在命令行上或通过其激活配置激活POM中的配置文件时,默认情况下激活的所有配置文件都将自动停用。
单词 inherit 让我感到困惑,因为“profile继承”在项目聚合中有效,但在项目继承中无效。
为了使事情更清楚,我模拟了这种情况。Empty 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目录是否存在,都从child目录输出运行mvn help:all-profiles

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


当从child目录运行mvn help:effective-pom时,它显示配置文件确实没有被继承。它的行为如文档所示:
POM中合并的元素如下:

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

这里没有提到配置文件。

项目聚合

目录结构:

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


模块pom是空的,而聚合器pom具有简单场景中的配置文件。如果没有aggregation/module/dir目录运行mvn help:all-profilesmodule目录输出:

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


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

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


当从module目录运行mvn help:effective-pom时,它显示配置文件被继承。这没有明确记录:

项目继承

如果您有多个Maven项目,并且它们都有类似的配置,您可以通过提取这些类似的配置并创建父项目来重构您的项目。因此,您所要做的就是让您的Maven项目继承该父项目,然后这些配置将应用于所有项目。
备注:

  • 这并不适用于配置文件,因为它已经显示。
  • inheritance目录运行maven构建将只运行父构建。
    项目汇总

如果你有一组一起构建或处理的项目,你可以创建一个父项目,并让该父项目将这些项目声明为它的模块。通过这样做,你只需要构建父项目,其余的都会随之而来。
备注:

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

总结

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

  • 当项目被继承时,配置文件 * 不会从父pom * 继承到子pom*。
  • 当项目被聚合时,配置文件 * 从聚合器pom被 * 继承到模块pom*。

这是使用Maven 3.1.0和3.0.5测试的。

m0rkklqb

m0rkklqb2#

只是为了澄清这一点,Maven配置文件实际上是继承的。关于另一个SO问题的参考,请参阅:Inheriting Maven profiles。我已经成功地在我的项目中继承了配置文件,不需要额外的工作。
对于最初的问题,您在exists元素中定义了一个变量。根据documentation
从Maven 2.0.9开始,标签和可以插值。支持的变量是系统属性(如${user.home})和环境变量(如${env.HOME})。请注意,POM本身中定义的属性和值在这里不能插值,例如,上面的示例激活器不能使用${project.build.directory},但需要硬编码路径目标。
所以,我从中得到的是,${project.basedir}不能使用,也不会工作。如果你把它定义为一个环境变量,它会工作。
我发现的一个警告是,在父pom中应该使用<plugin-management>来配置插件。然而,在配置文件中,我发现<plugin-management>不能用于特定于配置文件的配置。

jslywgbw

jslywgbw3#

问题不在于继承,而在于插值(即${...}支持哪些值):基于文件的配置文件激活仅支持有限插值:请参阅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

x4shl7ld

x4shl7ld4#

一般来说,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将不会处于活动状态。这是因为<activeByDefault>对于P1为真。在我看来,元素名称有点误导。“默认情况下活动”意味着“始终活动”,而实际上它的意思是“仅在此POM中没有其他配置文件处于活动状态时才活动”。
以上是使用Maven 3.0.x发现的。

30byixjq

30byixjq5#

从具有基于文件的激活的第二个配置文件中删除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>

字符串

相关问题