我的父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
在父项目中不存在,但存在于子项目中。
答案 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。由于聚合项目是一起构建的(在同一构建中),因此必须运行某种配置文件解析来计算活动项目。所以这是令人困惑的部分:
使用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>