1. Overview
1.概述
Maven allows us to build a project using the concept of inheritance. When a parent POM defines a plugin, all of the child modules inherit it.
Maven允许我们使用继承的概念来构建项目。当父级POM定义了一个插件时,所有的子模块都会继承它。
But what happens if we don’t want to inherit a plugin from a parent POM, and we can’t amend the parent POM?
但是,如果我们不想从父级POM中继承一个插件,而我们又不能修改父级POM,那该怎么办?
In this tutorial, we’ll look at a couple of different approaches to disabling a Maven plugin, specifically the Maven Enforcer Plugin, defined in a parent POM.
在本教程中,我们将探讨禁用Maven插件的几种不同方法,特别是定义在父POM中的Maven Enforcer插件。
2. When Would We Disable a Plugin Defined in the Parent POM?
2.什么时候我们会禁用一个在父POM中定义的插件?
Before we go any further, let’s think about why we might need to do this.
在我们进一步讨论之前,让我们想想为什么我们可能需要这样做。
Maven prefers convention over configuration. We need to remember that while disabling a plugin might be the quickest solution for us, it might not be the best solution for the project.
Maven更倾向于约定俗成的配置。我们需要记住,虽然禁用一个插件对我们来说可能是最快的解决方案,但对项目来说可能不是最好的解决方案。
The need to disable a plugin in the parent POM may arise when the original author of the Maven project did not foresee our situation, and we have no way to amend the parent module ourselves.
当Maven项目的原作者没有预见到我们的情况,而我们又没有办法自己修改父模块时,就可能需要在父POM中禁用一个插件。
Let’s say the original author assumed that a particular file should always exist. However, it doesn’t make sense for our module to have this file. For example, the parent POM might enforce the presence of a license file in each module, which we don’t have. Rather than add an empty file, which may be confusing, we want to disable the rule enforcement.
比方说,原作者认为某个文件应该永远存在。然而,我们的模块拥有这个文件是没有意义的。例如,父级POM可能会强制要求每个模块都有一个许可文件,而我们没有这个文件。与其添加一个空文件,可能会引起混淆,我们不如禁用规则的执行。
Let’s set up this scenario by adding a parent module in our Maven project that implements maven-enforcer-plugin:
让我们在Maven项目中添加一个实现maven-enforcer-plugin的父模块,来设置这个场景。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
</plugin>
Next, let’s add an execution to the plugin to enforce a rule that a file named file-that-must-exist.txt must exist within each module’s src directory:
接下来,让我们为该插件添加一个执行规则,即每个模块的src目录下必须存在一个名为file-that-must-exist.txt的文件。
<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>
If file-that-must-exist.txt doesn’t exist, then the build will fail.
如果file-that-must-exist.txt不存在,那么构建将失败。
As child modules inherit plugins from their parents, all of the child modules must abide by this rule.
由于子模块从其父模块继承插件,所有的子模块都必须遵守这一规则。
Let’s take a look at a couple of ways we could disable this rule in our child POM.
让我们看一下我们可以在我们的子POM中禁用这一规则的几种方法。
3. How Do We Disable a Plugin Defined in the Parent POM?
3.我们如何禁用一个在父级POM中定义的插件?
First, let’s assume that restructuring the Maven project or changing the parent POM aren’t acceptable solutions. If we could amend the parent module, then we could resolve this issue by implementing a pluginManagement section in the parent POM.
首先,我们假设重组Maven项目或改变父POM都不是可接受的解决方案。如果我们能修改父模块,那么我们可以通过在父POM中实施pluginManagement部分来解决这个问题。。
We might be unable to amend the parent module because we don’t own the project, so we’re not authorized to make changes outside of our module. It could be due to time constraints – restructuring a project takes time, so it’s just more convenient to disable a plugin in a child module.
我们可能无法修改父模块,因为我们不拥有这个项目,所以我们无权在我们的模块之外进行修改。这可能是由于时间限制 – 重组一个项目需要时间,所以只是在子模块中禁用一个插件更方便。
Further, we’re going to assume that the plugin actually needs to be disabled. Lots of plugins will run with no issues, even on modules they’re not intended for.
此外,我们将假设该插件实际上需要被禁用。许多插件将毫无问题地运行,即使在它们不打算使用的模块上。
For example, let’s say that we have a plugin that copies Java files. If we have a child project with no Java files, then the plugin is likely to simply not copy any files. It’ll do this without causing a problem. In this case, it’s simpler and more conventional to leave the plugin running.
例如,假设我们有一个复制Java文件的插件。如果我们有一个没有Java文件的子项目,那么这个插件可能就不会复制任何文件。它这样做不会引起问题。在这种情况下,让该插件继续运行是比较简单和常规的。
Let’s assume that after considering the above, we definitely need to disable the plugin with our module.
让我们假设在考虑了上述情况后,我们肯定需要用我们的模块禁用该插件。
One way we can do this is to configure the skip parameter.
我们可以做到这一点的一个方法是配置skip参数。
3.1. Configure the Skip Parameter
3.1.配置Skip参数
Many plugins feature a skip parameter. We can use the skip parameter to disable the plugin.
许多插件都有一个skip参数。我们可以使用skip参数来停用该插件。
If we take a look at the documentation for the maven-enforcer-plugin, we can see that it has a skip parameter that we can implement.
如果我们看一下maven-enforcer-plugin的文档,可以看到它有一个skip参数,我们可以实现。
Support for the skip parameter should be the first thing we check because it is the simplest solution and the most conventional.
对skip参数的支持应该是我们首先检查的,因为它是最简单的解决方案,也是最传统的。
Let’s add an empty child module, only containing the POM. If we build the module using a mvn clean install command, we see that the build fails. This is because file-that-must-exist.txt doesn’t exist within our module, which was required due to inheriting the rule from our parent module.
让我们添加一个空的子模块,只包含POM。如果我们使用mvn clean install命令来构建模块,我们看到构建失败。这是因为file-that-must-exist.txt在我们的模块中不存在,这是由于从我们的父模块继承规则而需要的。
Let’s add the following lines to the child POM to enable the skip parameter:
让我们在子POM中添加以下几行来启用skip参数。
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
Now, if we run the project, we see that the build is successful.
现在,如果我们运行该项目,我们看到构建成功了。
However, not all plugins will have a skip parameter. So if we’re using a plugin that doesn’t have one, what can we do instead?
然而,并非所有的插件都有skip参数。因此,如果我们使用的插件没有这个参数,我们可以怎么做呢?
3.2. Remove the Phase Parameter
3.2.删除相位参数
A Maven goal only runs when bound to a build phase.
一个Maven目标只有在绑定到构建阶段时才会运行,。
In our parent POM, we’ve configured the enforce goal to run with the id enforce-file-exists.
在我们的上级POM中,我们已经配置了强制目标,使其以enforce-file-exists的id运行。
As we haven’t specified a phase parameter for enforce-file-exists, it’ll use the default value for the enforce goal. We can see from the documentation that the default is the validate build phase.
由于我们没有为enforce-file-exists指定一个阶段参数,它将使用默认值作为强制目标。我们可以从文档中看到,默认的是validate构建阶段。
We can execute the goal in an alternative build phase by specifying an alternative value for the phase parameter.
我们可以通过为phase参数指定一个替代值,在另一个构建阶段执行该目标。
Using this to our advantage, we can set the phase parameter to a value that doesn’t exist. This means that the build phase would never be executed. Thus the goal wouldn’t be executed, effectively disabling the plugin:
利用这个优势,我们可以将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>
To make it clear to somebody looking at our code later, we’d want to set phase to a clear name such as “none” or “null”.
为了让后来看我们代码的人清楚,我们想把phase设置为一个明确的名字,如 “none “或 “null”。
However, perhaps the clearest way to do this would be to clear the phase parameter altogether:
然而,也许最清楚的方法是完全清除phase参数。
<execution>
<id>enforce-file-exists</id>
<phase/>
</execution>
As the phase of the execution empty is now empty, the goal won’t be bound to a build phase that runs. This effectively disables the plugin.
由于执行空的阶段现在是空的,目标不会被绑定到运行的构建阶段。这就有效地禁用了该插件。
We can see that when we run the build, enforce-file-exists doesn’t run at all for our child module.
我们可以看到,当我们运行构建时,enforce-file-exists对我们的子模块根本没有运行。
4. Conclusion
4.总结
In this article, we discussed why we might choose to disable a plugin defined in a parent POM. We saw that disabling the plugin might not always be the best thing to do, as Maven prefers convention over configuration.
在这篇文章中,我们讨论了为什么我们会选择禁用一个定义在父POM中的插件。我们看到,禁用该插件并不总是最好的办法,因为Maven更喜欢约定俗成的配置。
Then, we looked at a simple example where we disabled the maven-enforcer-plugin declared by a parent POM.
然后,我们看了一个简单的例子,我们禁用了一个父POM声明的maven-enforcer-plugin。
Firstly, we demonstrated that we could configure a plugin’s skip parameter if the plugin has one. We found that this was the most conventional approach.
首先,我们展示了我们可以配置一个插件的skip参数,如果该插件有的话。我们发现这是最传统的方法。
Finally, we learned that clearing the phase parameter for the plugin would effectively disable it.
最后,我们了解到,清除插件的phase参数将有效地禁用它。
As always, the example project is available over on GitHub.
一如既往,该示例项目可在GitHub上获得。