从Maven中的POM文件读取属性文件

Deb*_*Das 20 pom.xml maven

为什么这不起作用?如何从属性文件中选择版本号.

在pom.xml中读取属性

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
          </execution>
          <configuration>
            <files>
              <file>dev.properties</file>
            </files>
          </configuration>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
Run Code Online (Sandbox Code Playgroud)

在dev.properties中

org.aspectj.aspectjrt.version = 1.6.11

pom.xml中的依赖关系

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj.aspectjrt.version}</version>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

错误:依赖项必须是有效版本

Ste*_*lly 85

当您从命令行启动Maven时,它会经历多个阶段.这是对这些阶段的伪描述,我故意简化了确切的排序(存在说出稍微不正确/乱序的风险),这样你就可以看出为什么你要做的事情无法奏效.

  1. 首先它解析你的命令行,在命令行上定义的任何属性-Dname=value都被注入到MavenSession

  2. 检查定义命令行选项的反应器以确定要构建的项目列表(也称为反应器)应该是什么.-N表示只构建根pom.xml,-pl允许指定要构建的模块列表,-am-amd允许分别添加上游或下游模块-pl.Maven此时尚未解析任何pom.xml文件.

  3. -P配置文件激活规则进行解析,看看有什么配置文件来激活.

  4. 现在,Maven有足够的知识开始解析pom.xml文件.它首先加载和解析根pom.xml,即当前目录中的那个(或者如果你指定了一个替代pom.xml,-f那么).这个初始解析只是集中精力搞清楚要构建的项目列表.仅激活配置文件激活,因为它可能会影响<modules>可用的列表.Group Id,Artifact Id,Version和Packaging中的坐标pom.xml不能包含属性,因为此时的属性解析pom.xml尚未发生.(细心的读者也会看到,这也解释了为什么你不能根据其中的属性激活配置文件pom.xml,因为在此阶段只解析了系统属性)

  5. 一旦验证了项目集,Maven现在会对这些pom.xml文件进行一些解析,以构建构建扩展列表(如果有的话)和插件列表.在这个阶段,解析需要评估<properties>每个项目中的内容,因此这是在评估并"注入"有效模型时.因此可以使用系统属性和POM属性来定义内的坐标和附加的依赖关系(xpath的)/project/build/extensions,/project/build/pluginManagement/plugins/plugin,/project/build/pluginManagement/plugins/plugin/dependencies,/project/build/plugins/plugin/project/build/plugins/plugin/dependencies.

  6. 现在,Maven开始解析命令行中指定的目标和阶段列表.评估部分指定的目标以匹配插件列表.对于将执行插件目标的所有项目,匹配必须是唯一的(即,如果它是聚合器目标,则仅在根处需要匹配,但对于所有其他"正常"目标,插件短名称必须是适用于所有项目的插件).生命周期阶段必须来自其中一个默认生命周期,或者来自构建扩展中定义的生命周期.

  7. 从解析的目标和阶段列表中,Maven构建构建计划,即它将在哪些项目以及以何种顺序执行.为此,Maven必须解析reactor项目pom.xml文件中定义的项目依赖项列表.这是因为依赖性可能由反应器内的另一个项目产生,从而迫使项目执行的顺序.因此,您可以使用系统属性和pom属性来定义(xpath)中的坐标和其他依赖项/project/dependencyManagement/dependencies/dependency,/project/dependencies/dependency 但请注意,此时尚未执行任何插件.

  8. 现在Maven有了构建计划,它按照构建的顺序开始遵循该计划.如果CLI上的第一个目标/阶段是目标,那么将调用该目标.如果第一个目标/阶段是默认构建生命周期的一个阶段,那么Maven将从initialize阶段开始并执行绑定到该阶段的所有插件......在阶段列表中以类似的方式继续,然后是项目列表.另请注意,initialize阶段仅作为默认构建生命周期的一部分执行.它不会在默认的干净或默认站点生命周期上执行,也不会在任何自定义生命周期上执行.(细心的读者会得出结论,这突出了问题正在尝试的技术的另一个问题).注:请记住,聚合器目标形成了在反应器中的"破发",所以如果你问Maven来运行clean package foo:bar site,其中foo:bar是一个聚合的魔力目标,然后clean package将针对该反应器的所有项目中运行,那么foo:bar将会对root运行然后site将对抗反应堆中的所有项目.换句话说,构建计划将采用最长连续的非聚合器目标和阶段,按最长连续的聚合器目标进行划分.

  9. 在调用每个mojo(即绑定到某个阶段或直接从命令行指定的目标)之前,Maven会评估该mojo pom.xml的有效性<configuration>.此时,Maven可以使用系统属性,pom中指定的属性以及MavenSession先前执行的mojos 注入的任何属性.因此<configuration>可以参考任何这些属性......

    在旁边

    现在有一个警告......如果你说设置(的XPath)/project/build/directory${some-property-i-will-set-via-a-mojo},然后引用,从你<configuration>,以及这一不幸的消息是,(的XPath)/project/build/directory将被评估为有效pom.xml 之前,任何插件运行,所以${project.build.directory}会被赋予了字面值${some-property-i-will-set-via-a-mojo} ,这是类型java.io.File,MavenProject所以你实际会发生的是new File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}").如果<configuration>您要注入的字段是类型File,则不需要进行类型转换,因此将直接注入该值,并且不会发生属性替换.

    还有其他边缘情况,如上面概述的情况,但通常属性替换将在部分内使用"mojo注入"属性(例如Mojo的Properties Maven插件提供的属性)<configuration>.它不会在这些部分之外工作.

所以这里是斯蒂芬对不同房产类型的快速经验法则:

系统属性

这些工作无处不在......但是非常危险,/project/(parent/)?/(groupId|artifactId|version|packaging)因为当项目作为传递依赖项被拉入时,您无法控制什么样的系统属性.${...}在内部使用膨胀/project/(parent/)?/(groupId|artifactId|version|packaging)应该被认为相当于以200kph的速度驾驶汽车,方向盘上突出的30厘米(12英寸)金属钉代替安全气囊......哦,没有安全带......你只是有10个单位的酒精和两行可卡因.

pom.xml属性(和settings.xml属性)

这些在大多数地方都可以工作,但从未在其中可用/project/(parent/)?/(groupId|artifactId|version|packaging)(因为它们在评估这些字段时尚未解析)并且不能用于考虑活动配置文件(同样,因为在评估配置文件激活时尚未解析它们)

Mojo注入属性

这些工作在<configuration>部分内部并且可能(由于注入的Mojo String参数的递归插值)在间接使用时起作用,但考虑到所涉及的不确定性,建议仅将它们的使用限制<configuration>在插件和报告部分.

最后一件事

考虑将项目列为依赖项时会发生什么.如果您通过使用mojo从.properties磁盘上的文件中提取它们来指定其依赖项,则当从Maven存储库中提取依赖项时,Maven无法复制该依赖项.所以Maven无法确定依赖关系.因此它永远不会奏效.

您可以做的是使用外部系统(例如ANT)pom.xml从模板中生成替换为该文件的版本.然后使用实例化的模板进行构建.

  • 我从来没有如此完全满意但对答案如此彻底失望;) (3认同)
  • 这个解释真是太棒了!+100 (2认同)