maven之插件验证在Maven中如何工作,为什么它用无效版本构建我的项目

jackei 阅读:33 2025-06-02 22:19:02 评论:0

我有一个Maven项目,即使我在POM中指定了一个完全无效的插件,也可以正常运行:

<build> 
  <plugins> 
    <plugin> 
      <groupId>bla</groupId> 
      <artifactId>bar</artifactId> 
      <version>1.9.553342342343</version> 
      <executions> 
        <execution> 
          <phase>compile</phase> 
        </execution> 
      </executions> 
      <configuration> 
        <project> 
          <inceptionYear>123123</inceptionYear> 
          <contributors> 
            asdad 
          </contributors> 
        </project> 
      </configuration> 
    </plugin> 
  </plugins> 
</build> 

我也没有在Eclipse中看到任何错误,即使删除了 ~.m2\repository文件夹之后,它仍然可以正常运行。 Maven验证插件的方式是否有所改变?还是当我宣布目标被炸毁时首先出现?

请您参考如下方法:

您的问题提出了不同的问题,即由Maven执行的验证检查的种类以及实际执行的时间。坐好,有很多话要说。

步骤1:模型验证

在构建项目模型时,就在构建开始时就完成了第一组验证。此过程由Model Builder组件完成,其目标是将POM文件解析为Model对象(以便以后可以从中创建完整的MavenProject对象,从而显着执行依赖关系调解)。该验证步骤实际上分为两部分:

  • 一个raw model validation,在应用任何继承或任何内容之前,会在POM上进行解释。它寻找缺少的必需值,例如是否存在groupIdartifactIdversion;仓库有一个ID;或者,在您的情况下,该插件具有groupIdartifactId。实际上,它不会检查是否有版本,因为该版本可以被继承,但尚未完成。
  • 一个effective model validation,在继承,插值和配置文件/默认注入之后执行。此时,该模型应该是完全有效的。值得注意的是,它必须具有packaging,每个依赖项必须具有一个版本,每个插件也必须具有一个版本,依此类推。从技术上来说,1.9.553342342343是一个可接受的版本号,因此您拥有的插件版本实际上是完全有效的。实际上,几乎所有的String都可以作为有效的版本号。 the illegal characters are \\/:\"<>|?*。同样,插件的<configuration>未被验证,仅仅是因为它不能:这是针对每个插件的,并且可能会声明一个<project>参数。出于同样的原因,它不会检查插件是否真正存在于远程存储库中,或者是否指定了任何目标,阶段等。

  • 因此,在此步骤结束时,该POM已完全验证并且完全可以。

    步骤2:建立专案

    然后是实际上 building the MavenProject from it的步骤。因为Maven需要对项目的依赖项执行依赖关系中介,所以它首先必须下载它们。因此,如果您有任何无效的依赖项(即无法通过设置或项目本身中配置的远程存储库解决的依赖项),则将在此处停止。

    但是,如果我们假设可以正确解决依赖关系,则构建将继续逐个调用每个插件。重要的一点是,只有在Maven检测到将在构建过程中调用它们时,才会解析插件及其各自的依赖项。如果没有,Maven将不会尝试下载任何内容。此外,在实际调用插件并将值注入到插件中以供其使用时,也会完成插件配置的验证。

    根据启动的Maven命令,并非POM中声明的所有插件都可以工作。例如,如果用户输入了阶段,例如 mvn clean packagethen every plugin bound to a phase of the clean lifecycle, or the default lifecycle up to package , will be invoked;因此绑定(bind)到 install阶段的任何插件都不会被调用。同样,如果用户输入了一个目标(例如 mvn org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean),则只会调用该特定插件的特定目标,而所有其他插件都将被忽略。

    这最后一部分是为什么问题中的POM绝对不会给Maven带来麻烦,并且这里有很多要点:
  • 它绑定(bind)到compile阶段,但是它没有<goal>,因此即使要执行该阶段,插件也无能为力,因为没有定义目标。 Maven知道这一点,并且不会尝试解决插件工件。
  • 通过将<goal>添加到插件声明中,让我们将foo设置为<goals><goal>foo</goal></goals>并重新测试。我们在POM中:
    <executions> 
      <execution> 
        <phase>compile</phase> 
        <goals><goal>foo</goal></goals> 
      </execution> 
    </executions> 
    

    运行mvn cleanmvn clean validate仍然不会造成任何问题:compile阶段未执行。但是现在,如果我们运行mvn compile,我们最终会得到一个错误:

    插件bla:bar:1.9.553342342343或其依赖项之一无法解析

    毕竟,这就是我们想要的。由于插件声明的阶段为compile,并且所使用的命令将在该阶段运行,因此Maven尝试下载它(但失败)。
  • 因此,让我们删除该阶段。现在会发生什么?
    <executions> 
      <execution> 
        <goals><goal>foo</goal></goals> 
      </execution> 
    </executions> 
    

    实际上,在特定阶段运行任何命令(例如mvn cleanmvn validate)现在都会使构建失败。原因是插件可以具有a default phase(另请参见defaultPhase注释的目标上的 @Mojo 属性)。由于每个插件都可以自行决定是否为其目标提供默认阶段,因此Maven必须下载插件工件,并确定该特定插件是否使用默认插件。因此,我们的构建将再次失败,是的!

    如果用户调用特定目标,情况就不同了。尝试使用上面的mvn clean:clean,它不会失败。实际上,只会发出警告,指出Maven无法解决插件工件,但这都不是错误,因为调用clean:clean只会调用clean的特定maven-clean-plugin目标。实际上,从理论上讲,这里不应该有任何警告。 Maven不应尝试下载任何内容。使用前缀clean要求检查到远程存储库以解决它(refer to this answer to know how that works)是一个副作用。但是,如果使用mvn org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean对它进行完全限定,而无需任何插件前缀解析,则可以将错误/警告归零。
  • 最后,如果我们删除所有内容并最终得到
    <executions> 
      <execution> 
      </execution> 
    </executions> 
    

    应该很清楚,您将不执行任何操作都将导致错误,因为绝不能执行该插件。 (如果使用前缀,您仍然会收到警告)。

  • 步骤3:插件配置

    问题的最后一部分很简单:插件的配置验证。您会注意到这里根本没有提到这一点。这是因为它仅在实际执行插件时发生。而且由于它甚至不存在,因此不太可能执行。

    为了说明起见,我们假设它是。每个插件都配置有特定的 configurator。默认情况下为 it maps the XML elements to classes, fields, lists, maps, arrays, just like you would expect。您可以 provide your own configurator,但这不是一件简单的任务。实际上并没有执行任何实际的验证:基本上,如果配置器可以在mojo中连接适当的值,那么就完成了。您可以检查默认存在的 the different types of converters,但是归结为:未将字符串 "foo"指定为期望的整数值;如果插件期望,则传递正确的枚举名称;为自定义类传递适当的XML配置(即,每个字段都有其自己的XML元素)...值得指出的是,将 "foo"设置为预期的布尔属性不是问题,它将 false连接到该值中。

    最后,没有映射到mojo的任何参数的XML配置将被完全忽略,因此,即使存在 bar插件并且不带任何参数,在XML配置中传递 <project>也会被忽略,并且不会不会导致任何错误。


    标签:Maven
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号