我正在使用Maven进行一些测试,并意识到我可以执行Findbugs插件的findbugs
目标,而无需将插件添加到POM文件中。另一方面,当我需要运行Jetty插件的run
目标时,我被迫将插件添加到POM文件或构建失败。
当我运行第一个命令时,构建成功,而POM文件没有任何更改:
mvn findbugs:findbugs
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building module-mytest 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- findbugs-maven-plugin:3.0.4:findbugs (default-cli) @ module-mytest ---
[INFO] Fork Value is true
[java] Warnings generated: 6
[INFO] Done FindBugs Analysis....
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.165s
[INFO] Finished at: Sun Oct 23 18:40:26 WEST 2016
[INFO] Final Memory: 21M/111M
[INFO] -----------------------------------------------------------------------
但是当我跑第二个时,我得到了这个:
mvn jetty:run
[INFO] Scanning for projects...
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml (13 KB at 30.0 KB/sec)
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml (20 KB at 41.0 KB/sec)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.129s
[INFO] Finished at: Sun Oct 23 18:43:27 WEST 2016
[INFO] Final Memory: 12M/104M
[INFO] ------------------------------------------------------------------------
[ERROR] No plugin found for prefix 'jetty' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/home/hp-pc/.m2/repository), central (http://repo.maven.apache.org/maven2)] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoPluginFoundForPrefixException
因此,为了传递构建,我需要将以下内容添加到pom文件中:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.11.v20150529</version>
</plugin>
答案 0 :(得分:32)
您刚刚遇到了Maven的Plugin Prefix Resolution。这是一个允许用户通过使用其前缀来调用特定Maven插件的目标的功能。在命令行上直接调用目标时,可以使用功能齐全的形式:
mvn my.plugin.groupId:foo-maven-plugin:1.0.0:bar
这将调用具有坐标bar
的Foo Maven插件的目标my.plugin.groupId:foo-maven-plugin:1.0.0
(以groupId:artifactId:version
的形式)。它运作良好,但有点冗长。如果不指定所有这些坐标,以更简单的方式调用此目标会很好。 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
参数配置自己的分配。
在命令
中mvn foo:bar
Maven必须有办法推断出foo
实际上意味着my.plugin.groupId:foo-maven-plugin
。在settings.xml
文件中,您可以添加plugin groups,格式为:
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
这样做是告诉Maven当你在命令中使用前缀时应该考虑哪个组ID。默认情况下,除了设置中指定的组Maven also searches the group ids org.apache.maven.plugins
and org.codehaus.mojo
之外。它会在您在设置中配置的默认值之后搜索这些默认值。因此,通过上面的配置和mvn foo:bar
的命令,Maven将在组ID foo
,org.mortbay.jetty
和{{中找到一个前缀为org.apache.maven.plugins
的插件1}}。
第二步是如何实际执行搜索。 Maven将从这些组ID的每个远程存储库下载元数据文件(或者如果它们已经下载,则将其查看到本地存储库中),称为org.codehaus.mojo
。如果我们举例说明我们唯一的远程存储库是Maven Central,Maven将首先下载http://repo1.maven.org/maven2/org/mortbay/jetty/maven-metadata.xml
,如果我们有映射maven-metadata.xml
的内容,请查看此文件。请注意组ID是如何转换为远程存储库中的目录结构的。此元数据文件的结构是:
foo
如果<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,点击{{3} }。同样,如果没有找到,Maven将最终点击http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
(注意Downloading:
命令中的mvn jetty:run
日志,正好获取最后两个文件)。如果还没有找到,Maven就不能再为你做什么,而且会出错:
[错误]找不到前缀&#39; foo&#39;的插件在当前项目和插件组[org.mortbay.jetty,org.apache.maven.plugins,org.codehaus.mojo]中可从存储库[local(... /。m2 / repository),central({ {3}} - &gt; [帮助1]
这是你在这里遇到的错误。但是,如果在此搜索期间进行了一次匹配,则Maven可以推断出要使用的<artifactId>
。
现在意味着它具有组ID和工件ID。最后一块拼图是版本
Maven将采用最新的可用,除非在POM中明确配置(参见下一节)。通过获取另一个仍然称为maven-metadata.xml
的元数据文件来检索所有可能的版本,但这次与存储库中的工件id文件夹一起生存(与上面的文件夹文件文件夹相反,它与组ID一起)。以Maven Clean插件(其组ID和工件ID将通过上述机制和命令mvn clean:clean
找到)为例,http://repo1.maven.org/maven2/org/apache/maven/plugins/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 http://repo.maven.apache.org/maven2)] <release>
版本,代表插件的最新发布版本。如果该标记不存在,则会选择代表插件,发行版或快照的最新版本的<latest>
。可能会发生两个标记都不存在,在这种情况下,Maven maven-metadata.xml
,<version>
元素列表。
如果仍然失败,Maven就不能再为你做什么了,版本无法推断出来并且错误。但这不太可能发生。我们现在收集了组ID,工件ID和版本;是时候最终调用插件的bar
目标了。
如上所述,Maven查看活动远程存储库中的某些预定义组ID以查找具有给定前缀的匹配项。使用命令
mvn findbugs:findbugs
Maven以findbugs
前缀开始搜索。由于我们的配置在我们的设置中没有任何<pluginGroup>
,因此Maven会查找org.codehaus.mojo
和org.apache.maven.plugins
组ID以获得前缀匹配。
它找到了一个:will select as version在org.codehaus.mojo
组ID下发布;的确,你可以找到它will select the first release, or the first snapshot for lack of a release:
<plugin>
<name>FindBugs Maven Plugin</name>
<prefix>findbugs</prefix>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
您还可以通过查看findbugs-maven-plugin
刚刚推导出的Findbugs Maven Plugin文件(在撰写本文时为3.0.4)找到将要使用的版本;并注意它是如何使用的与您问题的mvn findbugs:findbugs
日志中的版本完全匹配。所以解决方案成功了,然后Maven可以继续调用此插件的in the maven-metadata.xml
目标。
第二个例子是命令
mvn jetty:run
与以前一样,会发生相同的解决步骤,但是,在这种情况下,您会发现前缀<jetty>
没有出现在任何maven-metadata.xml
组ID中{ {1}}和org.codehaus.mojo
。所以解决方案失败了,Maven会返回你的错误。
但我们已经看到了如何让它发挥作用!我们可以在设置中添加org.apache.maven.plugins
,以便在解析期间也可以搜索此组ID。 maven-metadata.xml
已在小组ID <pluginGroup>
下发布,如果我们查看相应的findbugs
,您会看到org.eclipse.jetty
在那里。因此修复很简单:只需定义此新组ID即可在设置中进行搜索:
<prefix>jetty</prefix>
现在,Maven还会查看此组ID,并将<pluginGroups>
<pluginGroup>org.eclipse.jetty</pluginGroup>
</pluginGroups>
前缀与jetty
成功匹配。
当然,如果您在POM中明确定义插件,则可以侧面跟踪所有这些解决方案,这是您找到的另一种解决方案:
org.eclipse.jetty:jetty-maven-plugin
并使用
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.11.v20150529</version>
</plugin>
如果您直接在POM中配置插件,前缀解析仍然会发生,但它有点掩盖:Maven将从配置的远程存储库下载插件,并将沿途下载并安装所有元数据文件,包括mvn jetty:run
包含前缀maven-metadata.xml
的映射。因此,自动下载后,搜索总会成功。
另请注意,由于插件是在POM中定义的,因此您在设置中不需要任何jetty
:组ID是在POM中编写的。此外,它确保将使用版本9.2.11.v20150529,而不是最新版本。