从Maven中的POM文件读取属性文件 [英] Reading Properties file from POM file in Maven

查看:124
本文介绍了从Maven中的POM文件读取属性文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why is this NOT working ? How to pick the version numbers from the properties file.

在pom.xml中读取属性

Reading properties in 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>

在dev.properties中

In dev.properties

org.aspectj.aspectjrt.version = 1.6.11

org.aspectj.aspectjrt.version=1.6.11

pom.xml中的依赖性

Dependency in pom.xml

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj.aspectjrt.version}</version>
        </dependency>

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

Error : dependency must be a valid version

推荐答案

从命令行启动Maven时,它会经历多个阶段.这是对这些阶段的伪描述,我有意简化确切的顺序(可能会说出一些稍微不正确/乱序的风险),以便您可以了解为什么您尝试做的事情行不通.

When you start up Maven from the command line, it goes through a number of stages. Here is a pseudo description of these stages, I am intentionally simplifying the exact sequencing (with the risk of saying things that are slightly incorrect/out-of-order) so that you can see why what you are trying to do cannot work.

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

  1. First it parses your command line, any properties defined on the command line using the -Dname=value are injected into the MavenSession

检查反应堆定义命令行选项,以决定要构建的项目列表(也称为反应堆). -N表示仅构建根pom.xml-pl允许指定要构建的模块列表,-am-amd允许分别添加由-pl指定的模块的上游或下游模块. Maven目前尚未解析任何pom.xml文件.

The reactor defining command line options are checked to decide what the list of projects to build (also known as the reactor) should be. -N means build only the root pom.xml, -pl allows specifying a list of modules to build, -am and -amd allows adding upstream or downstream, respectively, modules from those specified by -pl. Maven has not parsed any pom.xml files at this point in time.

解析-P配置文件激活规则以查看要激活的配置文件.

The -P profile activation rules are parsed to see what profiles to activate.

现在,Maven具有足够的知识来开始解析pom.xml文件.它首先加载并解析根pom.xml,即当前目录中的根(或如果您用-f指定了替代pom.xml,则是该目录).最初的解析只是专注于确定要构建的项目列表.仅考虑了概要文件激活,因为它可能会影响可用的<modules>列表. pom.xml中的组ID",工件ID",版本"和包装"坐标不能包含属性,因为pom.xml中的属性此时尚未进行解析. (细心的读者还将看到,这也解释了为什么您无法基于pom.xml中的属性来激活配置文件,因为在此阶段仅解析了系统属性)

Now Maven has enough knowledge to start parsing the pom.xml files. It starts by loading and parsing the root pom.xml, i.e. the one in the current directory (or if you specified an alternative pom.xml with -f then that one). This initial parse is just concentrating on figuring out the list of projects to build. Profile activation is only considered in so much as it may affect the list of <modules> that are available. The Group Id, Artifact Id, Version and Packaging coordinates in the pom.xml cannot contain properties because the parsing of the properties in the pom.xml has not taken place at this point in time. (The observant reader will also see that this also explains why you cannot activate profiles based on properties within the pom.xml, as only system properties have been parsed at this stage)

一旦验证了项目集,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中的坐标和其他依赖项.

Once the set of projects has been validated, Maven now does some more parsing of those pom.xml files to construct the list of build extensions (if any) and the list of plugins. At this stage the parsing requires evaluation of the <properties> in each project, so this is when these get evaluated and "injected" into the effective model. Thus you can use system properties and pom properties to define the coordinates and additional dependencies within (xpath) /project/build/extensions, /project/build/pluginManagement/plugins/plugin, /project/build/pluginManagement/plugins/plugin/dependencies, /project/build/plugins/plugin and /project/build/plugins/plugin/dependencies.

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

Now Maven starts parsing the list of goals and phases specified on the command line. Partially specified goals are evaluated for a match against the list of plugins. The match must be unique for all the projects that the plugin goal will be executed against (i.e. if it is an aggregator goal, the match is only required at the root, but for all other "normal" goals, the plugin short name must be the same plugin for all projects). Lifecycle phases must be from one of the default lifecycles, or from a lifecycle defined in a build extension.

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

From the parsed list of goals and phases, Maven constructs the build plan, i.e. what it is going to do on which projects and in what order. In order to do this Maven must parse the list of project dependencies defined in the reactor projects pom.xml files. This is because a dependency may be produced by another project within the reactor, thereby forcing a sequencing of project execution. Thus you can use system properties and pom properties to define the coordinates and additional dependencies within (xpath) /project/dependencyManagement/dependencies/dependency and /project/dependencies/dependency but note that at this point in time, no plugins have been executed.

现在Maven有了构建计划,它开始按照构建的顺序遵循该计划.如果CLI上的第一个目标/阶段是目标,则将调用该目标.如果第一个目标/阶段是默认构建生命周期的一个阶段,则Maven将以initialize阶段开始并执行绑定到该阶段的所有插件...以类似的方式沿阶段列表继续,然后项目清单.还要注意,initialize阶段仅作为默认构建生命周期的一部分执行.它不会在默认的清理或默认站点生命周期上执行,也不会在任何自定义生命周期上执行. (细心的读者将得出结论,这突出了该问题正在尝试的技术的另一个问题).注意:请记住,聚合器目标在反应堆中形成一个中断",因此,如果您要求Maven运行clean package foo:bar site,其中foo:bar是聚合器mojo目标,则clean package将针对该项目中的所有项目运行反应堆,然后foo:bar将针对根运行,然后site将针对反应堆中的所有项目运行.换句话说,构建计划将以最长的连续时间运行非聚合器目标&阶段,按聚合器目标的最长连续运行划分.

Now that Maven has the build plan, it starts following that plan in the order that it constructed. If the first goal/phase on the CLI was a goal, then that goal will be invoked. If the first goal/phase was a phase from the default build lifecycle, then Maven will start with the initialize phase and execute all the plugins bound to that phase... continuing in a similar manner along the list of phases and then the list of projects. Note also that the initialize phase is only executed as part of the default build lifecycle. It is not executed on the default clean or default site lifecycles, and it is not executed on any custom lifecycles. (The observant reader will conclude that this highlights another problem with the technique that the question is attempting). Note: keep in mind that aggregator goals form a "break" in the reactor, so if you ask Maven to run clean package foo:bar site where foo:bar is an aggregator mojo goal, then clean package will be run against all the projects in the reactor, then foo:bar will be run against the root, then site will be run against all the projects in the reactor. In other words, the build plan will take the longest continuous run of non-aggregator goals & phases, split by longest continuous runs of aggregator goals.

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

Before it calls each mojo (i.e. goal bound to a phase or directly specified from the command line) Maven evaluates the pom.xml for the effective <configuration> of that mojo. At this point Maven has available the system properties, the properties specified in the pom and any properties injected into the MavenSession by previously executed mojos. Thus the <configuration> can reference any of those properties...

在旁边

现在有一个警告...如果您说将(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} 类型的文字值${some-property-i-will-set-via-a-mojo} . MavenProject,所以您实际上将要发生的事情是new File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}").如果要注入的<configuration>字段的类型为File,则无需进行类型转换,因此将直接注入该值,并且不会进行任何属性替换.

Now there is a caveat... if you say set (xpath) /project/build/directory to ${some-property-i-will-set-via-a-mojo} and then reference that from your <configuration>, well the sad news is that (xpath) /project/build/directory will have been evaluated into the effective pom.xml before any plugin execution, so ${project.build.directory} will have been given the literal value ${some-property-i-will-set-via-a-mojo} and that is of type java.io.File in the MavenProject so what you will actually have had happen is new File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}"). If the <configuration> field you are injecting into is of type File, there will be no type conversion required, and hence the value will be injected straight in, and no property substitution will have taken place.

还有其他一些极端情况,例如上面概述的情况,但是通常属性替换将与"mojo注入"属性一起使用(例如

There are other edge cases, like the one outlined above, but in general property substitution will work with "mojo injected" properties (such as those provided by Mojo's Properties Maven Plugin) within the <configuration> sections. It will not work outside of those sections.

因此,这是斯蒂芬对不同属性类型的快速经验法则:

So here is Stephen's quick rule of thumb for the different property types:

系统属性

这些工作无处不在...但是在/project/(parent/)?/(groupId|artifactId|version|packaging)极其很危险,因为您无法控制将项目作为传递依赖项引入时将定义哪些系统属性.在/project/(parent/)?/(groupId|artifactId|version|packaging)中使用${...}扩展应该被认为等同于以200kph的速度驾驶汽车,该汽车具有从转向盘伸出的30cm(12英寸)金属钉,代替了安全气囊……哦,没有安全带. .而您刚喝了10单位酒精和两行可卡因.

These work everywhere... but are extremely dangerous in /project/(parent/)?/(groupId|artifactId|version|packaging) as you have no control what so ever on what system properties will be defined when the project is pulled in as a transitive dependency. Use of ${...} expansion within /project/(parent/)?/(groupId|artifactId|version|packaging) should be considered as equivalent to driving a car at 200kph with a 30cm (12 inch) metal spike protruding from the steering wheel in place of an airbag... oh and no seat belt... and you've just had 10 units of Alcohol and two lines of cocaine.

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

这些在大多数地方都可以使用,但是在/project/(parent/)?/(groupId|artifactId|version|packaging)中从不可用(因为在评估这些字段时尚未解析),也不能用于考虑活动配置文件(再次,因为在使用这些配置文件时尚未对其进行解析)个人资料激活正在评估中)

These work in most places, but are never available within /project/(parent/)?/(groupId|artifactId|version|packaging) (as they have not been parsed when those fields are being evaluated) and are not available for consideration of the active profiles (again as they have not been parsed when profile activation is being evaluated)

Mojo注入的属性

这些工作在<configuration>节中,并且可能(由于注入的Mojo String参数的递归插值)在间接使用时有效,但是鉴于所涉及的不确定性,建议将其限制在<configuration>节中使用仅插件和报告.

These work within <configuration> sections and may (due to the recursive interpolation of injected Mojo String parameters) work when used indirectly, but given the uncertainty involved, the recommendation is to restrict their use to the <configuration> section of plugins and reports only.

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

Think about what happens when your project is listed as a dependency. If you had specified its dependencies by using a mojo to pull those from a .properties file on disk, Maven has no way to replicate that when your dependency has been pulled from the Maven repository. So Maven would be unable to determine the dependencies. Thus it could never work.

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

What you could do, is use an external system (e.g. ANT) to generate the pom.xml from a template with the versions replaced into that file. And then use the instantiated template to build.

这篇关于从Maven中的POM文件读取属性文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆