即使我在POM中指定了一个完全无效的插件,我也有一个Maven项目可以正常构建:
if($_SERVER['REQUEST_METHOD'] == "POST"){
//search ajax handler goes here
$keyword= $_POST['keyword'];//the search keyword
//apply the search you want here, (for example database query)
$searchResult = ["result1","result2","result3","result4","result5"];
$searchResult = json_encode($searchResult );
die($searchResult );
}
我也没有在Eclipse中看到任何错误,甚至在删除<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>
文件夹后,它仍然可以正常运行。 Maven如何验证插件有什么变化?或者,当我宣布一个目标爆炸时,它是第一个吗?
答案 0 :(得分:4)
您的问题引发了不同的问题,即由Maven执行的不同类型的验证检查,以及它们何时实际完成。坐下,有很多话要说。
第一组验证是在构建开始时完成的,当时构建了项目模型。此过程由Model Builder组件完成,其目标是将POM文件解析为Model
对象(以便稍后可以从中创建完整的MavenProject
对象,执行特别是依赖调解)。此验证步骤实际上分为两部分:
groupId
,artifactId
或version
的存在;该存储库具有id;或者,在这种情况下,插件包含groupId
和artifactId
。它实际上并没有检查是否有版本,因为版本可以继承,而且还没有完成。packaging
,每个依赖项都必须有一个版本,每个插件也必须有一个版本,等等。你所拥有的插件版本实际上是完全有效的,1.9.553342342343
从技术上讲是一个公认的版本号。实际上,几乎所有String都有资格作为有效的版本号; the illegal characters are \\/:\"<>|?*
。此外,插件的<configuration>
未经过验证,只是因为它无法针对每个插件进行验证,并且可能会声明<project>
参数。出于同样的原因,它不会检查插件是否实际存在于远程存储库中,或者是否指定了任何目标,阶段等。因此,在此步骤结束时,该POM已完全验证且完全正常。
然后是实际building the MavenProject
from it的步骤。因为Maven需要对项目的依赖项执行依赖项中介,所以首先必须下载它们。因此,如果您有任何无效的依赖项(即在设置或项目本身中无法使用已配置的远程存储库解析的依赖项),那么就会停在此处。
但是如果我们想象正确解析了依赖关系,那么构建将继续逐个调用每个插件。重要的一点是,只有在Maven检测到它们将在构建期间被调用时,才会解决插件及其各自的依赖关系。如果没有,Maven将不会尝试下载任何内容。此外,当实际调用插件并将值注入其中时,也会对插件的配置进行验证,以供其使用。
根据启动的Maven命令,并非所有在POM中声明的插件都有工作要做。例如,如果用户输入了阶段,例如mvn clean package
,then every plugin bound to a phase of the clean lifecycle, or the default lifecycle up to package
, will be invoked;所以任何绑定到install
阶段的插件都不会被调用。此外,如果用户输入目标,例如mvn org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean
,则只会调用该特定插件的特定目标,并且将忽略所有其他插件。
最后一部分就是为什么问题中的POM对Maven没有任何麻烦,以下是关于它的多点:
compile
阶段,但它没有<goal>
,所以即使要执行该阶段,插件也无法做到,因为没有目标已定义。 Maven知道这一点,并没有尝试解决插件工件。通过在插件声明中添加<goal>
,我们将foo
设置为<goals><goal>foo</goal></goals>
并重新测试。我们在POM中有:
<executions>
<execution>
<phase>compile</phase>
<goals><goal>foo</goal></goals>
</execution>
</executions>
运行mvn clean
或mvn clean validate
仍然会导致绝对没有问题:compile
阶段未执行。但现在,如果我们运行mvn compile
,我们最终会收到错误:
插件bla:bar:1.9.553342342343或其中一个依赖项无法解析
毕竟,这就是我们想要的。由于插件声明的阶段为compile
,并且使用的命令将运行该阶段,因此Maven会尝试下载(并失败)。
所以让我们删除相位。现在会发生什么?
<executions>
<execution>
<goals><goal>foo</goal></goals>
</execution>
</executions>
实际上,运行具有特定阶段的任何命令,例如mvn clean
或mvn validate
,现在将无法构建。原因是插件可以有a default phase(另请参阅@Mojo
注释目标上的defaultPhase
属性)。由于每个插件都可以自行决定为其任何目标提供默认阶段,因此Maven必须下载插件工件,并查明此特定插件是否使用默认值。所以,我们的构建将再次失败,耶!
如果用户调用特定目标,则会有不同的故事。请尝试使用上述mvn clean:clean
,但不会失败。实际上,警告只是打印出Maven无法解决插件工件,但这些都不是错误,因为调用clean:clean
只会调用特定的{{} 1}} clean
的目标。事实上,从理论上讲,这里不应该有任何警告; Maven不应该尝试下载任何东西。使用前缀maven-clean-plugin
要求检查远程存储库以解决它(refer to this answer to know how that works)这一事实带来了副作用。但是,如果您完全符合条件,并且不需要使用clean
进行任何插件前缀解析,那么您将返回零错误/警告。
最后,如果我们删除所有内容并最终以
结束mvn org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean
它应该非常清楚,你所做的任何事都不会导致错误,因为这个插件决不会被执行。 (如果使用前缀,您仍然会收到警告。)
问题的最后一部分是简单的:插件的配置验证。你会注意到这里没有提到过这个;这是因为它只在插件实际执行时才会发生。由于它甚至不存在,因此不太可能被执行。
为了便于解释,我们假设它是。每个插件都配置了特定的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,但它归结为:未将字符串<executions>
<execution>
</execution>
</executions>
指定为预期的整数值;如果插件期望的话,传递正确的枚举名称;为自定义类传递适当的XML配置(即每个字段都有自己的XML元素)...值得指出的是,将"foo"
设置为预期的布尔属性不是问题,它会导致{{1}进入价值。
最后,没有映射到mojo的任何参数的XML配置被完全忽略,因此即使"foo"
插件存在且没有采用任何参数,也传递{{1}在XML配置中只会被忽略,并且不会导致任何错误。