如何禁用父POM中定义的Maven插件

2023/05/24

1. 概述

Maven允许我们使用继承的概念来构建项目,当一个父POM定义一个插件时,所有的子模块都会继承它

但是如果我们不想从父POM继承插件,并且我们不能修改父POM,会发生什么?

在本教程中,我们将介绍几种不同的方法来禁用Maven插件,特别是在父POM中定义的Maven Enforcer插件

2. 我们什么时候禁用父POM中定义的插件?

在我们进一步讨论之前,让我们考虑一下为什么我们可能需要这样做。

Maven更喜欢约定而不是配置,我们需要记住,虽然禁用插件对我们来说可能是最快的解决方案,但对项目来说可能不是最好的解决方案。

当Maven项目的原作者没有预见到我们的情况,而我们又没有办法自己修改父模块时,可能会出现需要在父POM中禁用一个插件的情况

假设原作者假设某个特定文件应该始终存在,但是,我们的模块拥有这个文件没有意义。例如,父POM可能会强制在每个模块中存在一个许可证文件,而我们没有。我们不想添加一个可能会造成混淆的空文件,而是希望禁用强制规则。

让我们通过在Maven项目中添加一个实现maven-enforcer-plugin的父模块来设置此场景:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>3.0.0</version>
</plugin>

接下来,让我们向插件添加一个<execution>,以强制执行一个名为file-that-must-exist.txt的文件必须存在于每个模块的src目录中的规则:

<executions>
    <execution>
        <id>enforce-file-exists</id>
	<goals>
	    <goal>enforce</goal>
	</goals>
	<configuration>
	    <rules>
	        <requireFilesExist>
		    <files>
		        <file>${project.basedir}/src/file-that-must-exist.txt</file>
		    </files>
		</requireFilesExist>
            </rules>
	</configuration>
    </execution>
</executions>

如果file-that-must-exist.txt不存在,则构建将失败。

由于子模块从其父模块继承插件,因此所有子模块都必须遵守此规则

让我们看一下我们可以在我们的子POM中禁用此规则的几种方法。

3. 我们如何禁用父POM中定义的插件?

首先,让我们假设重构Maven项目或更改父POM不是可接受的解决方案,如果我们可以修改父模块,那么我们可以通过在父POM中实现pluginManagement部分来解决这个问题

我们可能无法修改父模块,因为我们不拥有该项目,因此我们无权在我们的模块之外进行更改。这可能是由于时间限制-重构项目需要时间,所以禁用子模块中的插件会更方便。

此外,我们将假设该插件实际上需要被禁用。许多插件将毫无问题地运行,即使在它们不打算使用的模块上也是如此。

例如,假设我们有一个复制Java文件的插件,如果我们有一个没有Java文件的子项目,那么该插件很可能根本不复制任何文件,它会在不引起问题的情况下执行此操作。在这种情况下,让插件继续运行更简单也更传统。

让我们假设在考虑了上述因素之后,我们肯定需要使用我们的模块禁用插件。

我们可以做到这一点的一种方法是配置skip参数。

3.1 配置skip参数

许多插件都有一个skip参数,我们可以使用skip参数来禁用插件

如果我们看一下maven-enforcer-plugin的文档,我们可以看到它有一个我们可以实现的skip参数。

对skip参数的支持应该是我们检查的第一件事,因为它是最简单和最常规的解决方案

让我们添加一个空的子模块,只包含POM文件。如果我们使用mvn clean install命令构建模块,我们会看到构建失败,这是因为file-that-must-exist.txt在我们的模块中不存在,这是由于从我们的父模块继承规则所必需的。

让我们将以下行添加到子POM以启用skip参数:

<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>

现在,如果我们运行该项目,我们会看到构建成功。

但是,并非所有插件都有skip参数。因此,如果我们使用的是一个没有skip参数的插件,我们该怎么办?

3.2 删除phase参数

Maven目标仅在绑定到构建阶段时运行

在我们的父POM中,我们配置了enforce目标以id enforce-file-exists运行。

由于我们没有为enforce-file-exists指定phase参数,因此它将使用默认值作为执行目标。我们从文档中可以看出,默认是validate构建阶段。

我们可以通过为phase参数指定替代值来在替代构建阶段执行目标。

利用这一点,我们可以将phase参数设置为不存在的值,这意味着永远不会执行构建阶段。因此目标不会被执行,有效地禁用了插件:

<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <executions>
        <execution>
            <id>enforce-file-exists</id>
	    <phase>any-value-that-is-not-a-phase</phase>
	</execution>
    </executions>
</plugin>

为了让以后查看我们代码的人清楚,我们希望将phase设置为一个清晰的名称,例如“none”或“null”。

然而,也许最清晰的方法是完全清除phase参数:

<execution>
    <id>enforce-file-exists</id>
    <phase/>
</execution>

由于执行phase现在为空,因此目标不会绑定到运行的构建阶段,这有效地禁用了插件。

我们可以看到,当我们运行构建时,enforce-file-exists根本不会为我们的子模块运行。

4. 总结

在本文中,我们讨论了为什么我们可能会选择禁用在父POM中定义的插件,我们看到禁用插件可能并不总是最好的做法,因为Maven更喜欢约定而不是配置。

然后,我们查看了一个简单示例,其中我们禁用了由父POM声明的maven-enforcer-plugin。

首先,我们演示了如果插件有skip参数,我们可以配置插件的skip参数,并且我们提到这是最传统的方法。

最后,我们了解到清除插件的phase参数也可以有效地禁用它

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章