Maven - 根据属性激活子配置文件

发布于 2024-08-06 13:35:08 字数 613 浏览 7 评论 0 原文

场景:

  1. 给定
    1. 定义配置文件和子项(作为模块)的父 POM
    2. 将通过引用父 POM 来使用配置文件的子项目。
  2. 目的是跳过父级中的配置文件执行并仅在子级中执行
  3. 配置文件具有激活部分foo
  4. 由于父级未定义 foo 属性 - 配置文件处于非活动状态,并且不会为父级构建执行
  5. 现在,我正在定义 true< ;/foo> 在子级中,希望在执行子级构建并激活配置文件时拾取该属性。没有这样的运气。配置文件从未被激活,这告诉我属性从未被设置。
  6. 只是要注意: mvn package -Dfoo=true 激活父级和子级中的配置文件

我是在尝试做不可能的事情还是只是做错了?

PS 嗯 - 即使我在父级中定义属性,配置文件也不会被触发。什么给?

Scenario:

  1. Given
    1. Parent POM which defines a profile and a child (as module)
    2. Child project(s) that will be using the profile by referring to the parent POM.
  2. The intent is to skip profile execution in the parent and execute it in the child only
  3. Profile has activation section <activation><property><name>foo</name></property><activation>
  4. Since parent does not define foo property - the profile is inactive and will not be executed for the parent build
  5. Now, I'm defining <properties><foo>true</foo></properties> in the child with hope that the property will be picked up when child build is executed and profile will be activated. No such luck. Profile is never activated, which tells me that property is never set.
  6. Just to note: mvn package -Dfoo=true activates profile in both parent and child

Am I trying to do the impossible or just doing it wrong?

P.S. Hmmm - even if I define property in the parent, the profile is not triggered. What gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黎夕旧梦 2024-08-13 13:35:08

为了扩展 @rich-seller 的答案和 @Bostone 的自我回答,似乎不可能进行这样的设置:父 POM 定义一些配置文件作为替代方案,而子 POM 默认选择这些配置文件之一,同时允许您暂时覆盖子项的选择(即在 CLI 上)。考虑使用某些框架和关联插件的项目的父 POM,我们可以假设它们的两个版本都是由属性定义的:

<profiles>
  <profile>
    <id>newest</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <framework.version>2.0</framework.version>
      <plugin.version>2.0</plugin.version>
    </properties>
  </profile>
  <profile>
    <id>older</id>
    <activation>
      <property>
        <name>older.framework</name>
        <value>true</value>
      </property>
    </activation>
    <properties>
      <framework.version>1.1</framework.version>
      <plugin.version>1.1</plugin.version>
    </properties>
  </profile>
</profiles>

现在默认情况下从此父 POM 继承的子项将使用 2.0,如您所料,并且 - Polder-Dolder.framework=true 将尝试使用旧框架构建它(例如测试兼容性)。但是,您无法在子 POM 中写入

<properties>
  <older.framework>true</older.framework>
</properties>

并自动激活older 配置文件。如果默认情况下 newest 未激活,您可以使用基于文件的激活来使此模块针对 1.1 进行构建,但是暂时针对 2.0 运行它并不容易:据我所知 -Pnewest,>older和newest配置文件将处于活动状态,因此您需要显式禁用其他配置文件,这是不合理的如果你有十几个。因此,除了将配置文件信息复制到子 POM 之外,没有其他解决方案:

<properties>
  <framework.version>1.1</framework.version>
  <plugin.version>1.1</plugin.version>
</properties>

此时 -Pnewest无法覆盖这些属性,因此您需要使用 <代码>-Dframework.version=2.0 -Dplugin.version=2.0。

换句话说,只有当所有子模块默认情况下都可以使用相同的配置文件(此处为最新)时,配置文件才有用。如果其中一些通常是用 1.1 构建的,另一些是用 2.0 构建的,则配置文件就没用了。

看起来这是 Maven 核心增强的用例,或者可能是 Maven 3 构建扩展。 http://docs.codehaus.org/display/MAVEN/Custom+Profile+Activators https://github.com/maoo/maven-tiles 浮现在脑海中。

To expand on @rich-seller's answer, and @Bostone's self-answer, it seems to be impossible to have a setup where the parent POM defines a few profiles as alternatives, and child POMs select one of these profiles by default, while allowing you to override the choice for a child temporarily (i.e. on the CLI). Consider a parent POM for projects which use some framework and an associated plugin, both of whose versions we can assume are defined by properties:

<profiles>
  <profile>
    <id>newest</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <framework.version>2.0</framework.version>
      <plugin.version>2.0</plugin.version>
    </properties>
  </profile>
  <profile>
    <id>older</id>
    <activation>
      <property>
        <name>older.framework</name>
        <value>true</value>
      </property>
    </activation>
    <properties>
      <framework.version>1.1</framework.version>
      <plugin.version>1.1</plugin.version>
    </properties>
  </profile>
</profiles>

Now a child inheriting from this parent POM by default will use 2.0 as you would expect, and -Polder or -Dolder.framework=true will work to try building it with the older framework (e.g. to test compatibility). However you cannot write in the child POM

<properties>
  <older.framework>true</older.framework>
</properties>

and have the older profile be activated automatically. You could use file-based activation to make this module build against 1.1 if newest were not active by default, but then it is not easy to temporarily run it against 2.0: as far as I know both older and newest profiles would be active if you passed -Pnewest, so you need to explicitly disable other profiles which is unreasonable if you have a dozen of them. So there is just no solution except to copy the profile information to the child POM:

<properties>
  <framework.version>1.1</framework.version>
  <plugin.version>1.1</plugin.version>
</properties>

at which point -Pnewest will not work to override these properties, so you need to use -Dframework.version=2.0 -Dplugin.version=2.0.

In other words, the profiles are only useful if all the child modules can use the same profile (here newest) by default. If some of them are normally built with 1.1 and some with 2.0, the profiles are useless.

Seems like this is a use case for a Maven core enhancement, or perhaps a Maven 3 build extension. http://docs.codehaus.org/display/MAVEN/Custom+Profile+Activators and https://github.com/maoo/maven-tiles come to mind.

无名指的心愿 2024-08-13 13:35:08

该配置文件只能通过从命令行传递的属性来激活。这是因为 POM 中的属性只有在解析 POM 后才能处理,此时解决配置文件激活问题已经为时已晚。

除非您能够从命令行传递属性,在 settings.xml 中指定配置文件激活(通常不是一个好主意),或者使用我的 < href="https://stackoverflow.com/questions/1501294/maven-skip-parent-project-build/1502322#1502322">上一个答案使用标记文件的存在。

如果您使用 Maven 2.1.0+,最后一个替代方案是仅通过父 POM 的命令行停用配置文件,这显然仍然不理想。

您可以使用字符“!”来停用配置文件或像这样的“-”:

mvn install -P !profile-1,!profile-2

The profile can only be activated by properties passed from the command line. This is because properties in the POM can only be processed once the POM has been parsed, at which point it is too late to resolve the profile activation.

You're in a bit of a catch-22 with this approach unless you are able to pass the property from the command line, specify profile activation in your settings.xml (generally not a great idea), or use the workaround in my previous answer to use the presence of a marker file.

One final alternative if you're on Maven 2.1.0+ is to deactivate the profile via the command line for the parent POM only, this is still obviously not ideal.

You can deactivate a profile with either the character '!' or '-' like this:

mvn install -P !profile-1,!profile-2
债姬 2024-08-13 13:35:08

直接回答我自己的问题:在多模块构建中,所有属性都在构建运行之前设置,因此不可能在其中一个模块期间激活/停用配置文件基于在子 POM 中设置属性来构建。但是,如果您正在寻找使用其他方式执行此操作的方法,请 阅读此评论

To directly answer my own question: in multi-module build all properties are set before build is run so it is impossible to activate/deactivate profile in one of the modules during the build based on setting the propety in the child POM. However if you are looking for way of doing it by using other means please read this comment

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文