Maven2 - pluginManagement和父子关系的问题

New*_*ian 16 maven-2

来自maven 文档

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

现在:如果我在父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>
Run Code Online (Sandbox Code Playgroud)

我在父项目上运行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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

并运行mvn help:有效-pom插件管理部分中的东西被添加到已声明的内容之上.因此 :

  <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>
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:

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

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

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

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

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

感谢大家的帮助 :-)

Ric*_*ler 13

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

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

但是,这仅配置在子节点的plugins元素中实际引用的插件

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

<build>
  <plugins>
    <plugin>
      <artifactId>maven-dependency-plugin</artifactId>
    </plugin>
  </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

更新:要回答实际问题,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>
Run Code Online (Sandbox Code Playgroud)

  • 我不担心分离父级和聚合器,你拥有的项目越多,它们整体上可能就越不相似,所以你越有可能定义具有不同父项的项目集,与你希望的分组正交建立他们.没有完美的答案.我认为它与OOP中的继承与组合相同. (2认同)

Cor*_*son 5

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

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

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

该死的.


Sta*_*sev 5

在父pom中,您应该使用声明配置执行<goals>,但不声明<phase>。然后在子 POM 中你应该声明:

<plugin>
  <artifactId>some-plugin</artifactId>
  <executions>
    <execution>
      <id>execution-id</id>
      <phase>partcular-phase</phase>
    </execution>
  </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

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

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

<execution>
  <id>execution-id</id>
  <goals><goal>some-goal</goal></goals>
  <phase>none</phase>
</execution>
Run Code Online (Sandbox Code Playgroud)