Maven2 - pluginManagement和父子关系的问题

时间:2009-08-12 13:38:15

标签: maven-2

来自maven documentation

  

pluginManagement:是一个沿侧插件看到的元素。插件管理以大致相同的方式包含插件元素,除了不是为这个特定的项目构建配置插件信息,它旨在配置从这个继承的项目构建。但是,这仅配置在子节点的plugins元素中实际引用的插件。孩子们有权覆盖插件管理定义。

现在:如果我在父POM中有这个

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

我在父项目上运行mvn help:effective-pom我得到了我想要的东西,即直接构建的插件部分(正在进行工作的部分)仍为空。

现在,如果我执行以下操作:

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <inherited>true</inherited>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
</plugins>
  </build>

mvn help:effective-pom我再次得到我想要的东西,插件包含声明的内容,并忽略了pluginManagement部分。

但改变如下

  <build>
   <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <executions>
             Some stuff for the children
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
            <executions>
             some stuff for adults only
            </execution>
          </executions>
       </plugin>
    </plugins>
  </build>

并运行mvn help:effective-pom pluginManagement部分中的内容添加在已声明的内容之上。就这样:

  <build>
   <pluginManagement>
     ...
   </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
          <version>2.0</version>
          <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
              <executions>
                 Some stuff for the children
                </execution>
            <executions>
             some stuff for adults only
            </execution>
          </executions>
       </plugin>
    </plugins>
  </build>

有没有办法从父pom的部分中排除儿童的部分?实际上我想要的是pluginManagement的行为与文档状态完全相同,即我希望它仅适用于子项,但不适用于声明它的项目。

作为一种证据,有没有办法可以通过在项目的正常构建部分中声明插件来覆盖pluginManagement中的部分?无论我尝试什么,我得到的部分被添加到执行中,但我不能覆盖已存在的部分。

编辑:

我从来没有找到一个可接受的解决方案,因此问题仍然存在。下面提供了最接近的解决方案,目前是这个问题的公认解决方案,直到出现更好的方案。现在有三种方法可以实现所需的结果(根据当前POM的继承层次结构调整插件行为):

1 - 使用配置文件,它会工作,但你必须要注意,配置文件不是继承的,这有点违反直觉。它们(如果激活)应用于声明的POM,然后生成的POM向下传播。因此,激活子POM的配置文件的唯一方法是在命令行上(至少我没有找到另一种方式)。属性,文件和其他激活方法无法激活POM,因为触发器不在声明配置文件的POM中。

2 - (这就是我最终要做的事情)将插件声明为不在父级中继承,并重新声明(复制 - 粘贴)每个需要它的子节点中的花絮。不理想,但很简单,也很有效。

3 - 拆分父POM的聚合性质和父性质。然后,因为仅适用于父项的部分位于不同的项目中,所以现在可以使用pluginManagement作为第一个预期。但是,这意味着必须创建一个新的人工项目,该项目不会对最终产品做出贡献,而只会为can系统提供服务。这是概念性流血的明显案例。这也仅适用于我的具体情况并且难以概括,所以我放弃了努力尝试使这项工作有利于2中描述的非常漂亮但更多包含的剪切和粘贴补丁。

如果遇到这个问题的人有更好的解决方案,或者是因为我对Maven缺乏了解,或者因为工具已经发展到允许这样做,请在此处发布解决方案以供将来参考。

谢谢大家的帮助: - )

4 个答案:

答案 0 :(得分:13)

将插件配置添加到pluginManagement意味着如果声明了插件,将使用此配置,但您仍需要在任何想要使用它的POM的构建部分中声明插件。

从您引用的部分解释这一点的关键部分是:

  

但是,这只配置在子项

中的plugins元素中实际引用的插件

因此,如果您在子pom中执行此操作,将应用来自父级的配置:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-dependency-plugin</artifactId>
    </plugin>
  </plugins>
</build>

更新:要回答实际问题,pluginManagement部分中的内容始终与任何插件声明合并。要避免父级执行此操作,您可以在配置文件中定义pluginManagement部分,并在子项目上激活该配置文件,但不在父项目上激活该配置文件。然后,子项目必须声明该配置文件。

例如:

<profiles>
  <profile>
    <id>for-children</id>
    <build>
      <pluginManagement>
        <plugins>
          <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.0</version>
            <executions>
              <!--Some stuff for the children-->
            </executions>
          </plugin>
        </plugins>
      </pluginManagement>
    </build>  
  </profile>
</profiles>
<build>
  <plugins>
    <plugin>
      <artifactId>maven-dependency-plugin</artifactId>
        <version>2.0</version>
        <inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
          <!--some stuff for adults only-->
        </executions>
     </plugin>
  </plugins>
</build>

答案 1 :(得分:5)

我总是认为子POM可以从其父插件管理部分继承插件定义,并通过 ID <引用它来指定它想要从该插件运行的执行。 / strong>并将执行绑定到阶段。只要定义在pluginManagement中(而不是直接在插件中)并且没有绑定到阶段,只有特定的执行(带有ID)将在该阶段运行。

通过阅读上述内容,以及我自己当前的问题,它看起来并非如此:它看起来像一个孩子POM将继承插件的整个配置,包括所有执行。在执行方面,孩子唯一可以做的就是覆盖特定的值 - 它不能选择要运行的执行,以及不执行哪些执行。

这是一个错误吗?如果所有执行都将运行,那么能够将每个执行绑定到某个阶段(或不绑定)的用途是什么?我只用maven-dependency-plugin看到它:unpack(绑定到 package 阶段),但是对于其他插件,我可能只是幸运...

该死。

答案 2 :(得分:3)

在父pom中,您应该配置已声明<goals>的执行,但不要声明<phase>。然后在孩子pom中你会宣布:

<plugin>
  <artifactId>some-plugin</artifactId>
  <executions>
    <execution>
      <id>execution-id</id>
      <phase>partcular-phase</phase>
    </execution>
  </executions>
</plugin>

在您定义子pom中的阶段之前,不会执行插件。因此,您需要将执行显式绑定到每个子pom(或层次结构中间)的阶段,但是 您不需要复制粘贴这些执行的配置。

注意,很多插件都有默认阶段,例如默认情况下,Enforcer插件绑定到validate。即使您没有明确地将插件绑定到某个阶段,它仍然会被绑定,因此插件将被执行。要解决此问题,请在父级中使用不存在的阶段:

<execution>
  <id>execution-id</id>
  <goals><goal>some-goal</goal></goals>
  <phase>none</phase>
</execution>

答案 3 :(得分:0)

你必须为执行分配一个ID,以便maven知道哪些是相互覆盖的,哪些是独立的。