您刚刚遇到了Maven
的插件前缀解析。此功能使用户可以使用其前缀来调用特定Maven插件的目标。在命令行上直接调用目标时,可以使用以下功能齐全的形式:
mvn my.plugin.groupId:foo-maven-plugin:1.0.0:bar
这将调用
bar具有坐标
my.plugin.groupId:foo-maven-plugin:1.0.0(以形式
groupId:artifactId:version)的Foo
Maven插件的目标。它运作良好,但是有点冗长。不用指定所有这些坐标就可以以一种更简单的方式调用此目标,这将是很好的。Maven通过为插件分配前缀来实现这一点,因此您可以使用以下前缀而不是整个坐标来引用该前缀:
如何确定此前缀?mvn foo:bar ^^^ ^^^ | | prefix | | goal
您可以为每个Maven插件定义一个前缀。这对应于用于标识它的简单名称:
使用的常规工件ID格式为:
maven-${prefix}-plugin-对于由Apache
Maven团队本身维护的官方插件(您不得为插件使用此命名模式,有关更多信息,请参阅此注释) ${prefix}-maven-plugin-用于其他来源的插件如果插件的artifactId符合此模式,Maven将自动将插件映射到存储库中插件的groupId路径中存储的元数据中的正确前缀。
换句话说,如果您的插件的工件ID被命名
foo-maven-plugin,Maven将自动为其分配前缀
foo。如果您不希望使用此默认分配,则仍然可以在
maven-plugin-plugin和
goalPrefix参数的帮助下自行配置。Maven如何将前缀映射到插件?
在命令中
mvn foo:bar
Maven必须有一种推断出
foo实际含义的方法
my.plugin.groupId:foo-maven-plugin。在
settings.xml文件中,您可以添加插件组,形式为:
<pluginGroups> <pluginGroup>org.mortbay.jetty</pluginGroup></pluginGroups>
这是在告诉Maven当您在命令中使用前缀时应该考虑哪个组ID。默认情况下,除了设置中指定的组外,Maven还搜索组ID
org.apache.maven.plugins和
org.prehaus.mojo。它会在您在设置中配置的默认值之后搜索这些默认值。因此,利用上述结构,和一个命令
mvnfoo:bar,Maven会寻找具有的前缀插件
foo组id内
org.mortbay.jetty,
org.apache.maven.plugins和
org.prehaus.mojo。
第二步是如何实际执行搜索。Maven
maven-metadata.xml将从每个远程存储库中的组ID
下载元数据文件(如果已下载,则将其查找到本地存储库中)。如果以我们仅有的远程存储库为Maven
Central的示例为例,则Maven首先下载
http://repo1.maven.org/maven2/org/mortbay/jetty/maven-metadata.xml,如果有映射,则在此文件中查找
foo。请注意,组ID是如何转换为远程存储库中的目录结构的。该元数据文件的结构为:
<metadata> <plugins> <plugin> <name>Some Awesome Maven Plugin</name> <prefix>somePrefix</prefix> <artifactId>some-maven-plugin</artifactId> </plugin> </plugins></metadata>
如果该
<plugin>节中没有包含
<prefix>与我们指定的(
foo)相等的节,则Maven将继续输入下一个组ID,即
http://repo1.maven.org/maven2/org/prehaus/mojo/maven-metadata.xml。再次,如果没有找到,Maven将最终命中
http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml(请注意命令中的
Downloading:日志
mvnjetty:run,正好获取了最后两个文件)。如果仍然找不到任何内容,那么Maven将无法为您做任何事情,并且会出错:
[错误]在存储库本地(..)中找不到在当前项目和插件组[org.mortbay.jetty,org.apache.maven.plugins,org.prehaus.mojo]中前缀为’foo’的插件。
./.m2/存储库),中央([http://repo.maven.apache.org/maven2)]
-> [帮助1]
这是您在这里的错误。但是,如果在此搜索过程中进行了匹配,则Maven可以推断出
<artifactId>要使用的匹配项。
现在,这意味着它具有组ID和工件ID。最后一个难题是版本
将使用哪个版本?除非在POM中明确配置,否则Maven将采用最新的版本(请参阅下一节)。通过获取另一个元数据文件(仍称为)来检索所有可能的版本
maven-metadata.xml,但这一次位于存储库中的工件ID文件夹旁边(与上面的相反,该文件夹位于组ID旁边)。以Maven
Clean插件为例(其组ID和工件ID可通过上述机制和的命令找到
mvn clean:clean),
maven-metadata.xml如下所示:
<metadata> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <versioning> <latest>3.0.0</latest> <release>3.0.0</release> <versions> <version>2.0-beta-1</version> <version>2.0-rc1</version> <version>2.0</version> <version>2.1</version> <!-- more versions --> <version>3.0.0</version> </versions> <lastUpdated>20151022205339</lastUpdated> </versioning></metadata>
Maven 将选择该
<release>版本作为版本,该版本代表插件的最新发行版本。如果没有该标签,它将选择
<latest>代表插件,发行版或快照的最新版本。可能会出现两个标签都不存在的情况,在这种情况下,Maven
将选择
<version>元素列表的第一个版本或缺少版本的第一个快照。
如果仍然失败,则Maven无法为您做任何事情,无法推断该版本,并且会出错。但这不太可能发生。现在,我们收集了组ID,工件ID和版本。是时候最终调用
bar我们插件的目标了。我的配置有什么问题?
如上所述,Maven在活动的远程存储库中查找某些预定义的组ID,以查找具有给定前缀的匹配项。用命令
mvn findbugs:findbugs
Maven使用
findbugs前缀开始搜索。由于我们的配置中没有任何
<pluginGroup>配置,因此Maven会查询
org.prehaus.mojo和
org.apache.maven.plugins组ID以查找前缀匹配项。
它确实找到了一个:Findbugs Maven插件在
org.prehaus.mojo组ID 下发布;确实,您可以在以下位置
maven-metadata.xml找到它:
<plugin> <name>FindBugs Maven Plugin</name> <prefix>findbugs</prefix> <artifactId>findbugs-maven-plugin</artifactId></plugin>
您还可以通过
maven-metadata.xml按
findbugs-maven-plugin刚推导出的文件(在撰写本文时为3.0.4;并注意
mvnfindbugs:findbugs问题日志中的版本与该版本完全匹配)下浏览该文件来找到要使用的版本。因此解析成功,然后Maven可以继续调用
findbugs此插件的目标。
第二个例子是命令
mvn jetty:run
与以前一样,执行相同的解析步骤,但是在这种情况下,您会发现前缀在组ID
和的
<jetty>任何中均未出现。因此解决方案失败,并且Maven返回您所具有的错误。
maven-metadata.xml``org.prehaus.mojo``org.apache.maven.plugins
但是,我们已经看到了如何使其工作!我们可以
<pluginGroup>在设置中添加一个内部,以便在解析过程中也可以搜索该组ID。该码头Maven插件是组ID下发布
org.eclipse.jetty的,如果我们窥视到相应
maven-metadata.xml的Maven的中央,你会发现
<prefix>jetty</prefix>在那里。因此解决方法很简单:只需定义此新的组ID即可在设置中进行搜索:
<pluginGroups> <pluginGroup>org.eclipse.jetty</pluginGroup></pluginGroups>
现在,Maven还将调查该组ID,并将
jetty前缀与
org.eclipse.jetty:jetty-maven-plugin成功匹配。如何使用特定版本?或者,我不想修改我的设置!
当然,如果您在POM中显式定义了插件,那么所有这些解决方案都可以忽略不计,这是您找到的另一个解决方案:
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.11.v20150529</version></plugin>
和使用
mvn jetty:run
如果您配置的POM直接插件,前缀分辨率仍然发生,但它是一个位屏蔽:Maven会从配置的远程资源库下载插件,并下载和安装的所有元数据文件一路上,包括
maven-metadata.xml含前缀的映射
jetty。因此,由于它会自动下载,因此搜索始终会成功。
还要注意,由于插件是在POM中定义的,因此您不需要任何
<pluginGroup>设置:组ID是在POM中编写的。此外,它确保将使用版本9.2.11.v20150529,而不是最新版本。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)