[英]How does Maven plugin prefix resolution work? Why is it resolving “findbugs” but not “jetty”?
我當時使用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>
您剛剛遇到了Maven的插件前綴解析 。 此功能使用戶能夠使用其前綴來調用特定Maven插件的目標。 在命令行上直接調用目標時,可以使用以下功能齊全的形式:
mvn my.plugin.groupId:foo-maven-plugin:1.0.0:bar
這將調用Foo Maven插件的目標bar
,其坐標為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
文件中,可以添加插件組 ,形式為:
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
這是在告訴Maven當您在命令中使用前綴時應該考慮哪個組ID。 默認情況下,除了設置中指定的組外, Maven還搜索組ID org.apache.maven.plugins
和org.codehaus.mojo
。 它會在您在設置中配置的默認值之后搜索這些默認值。 因此,使用上述配置以及mvn foo:bar
的命令,Maven將在組ID org.mortbay.jetty
, org.apache.maven.plugins
和org.codehaus.mojo
查找具有foo
前綴的插件。 。
第二步是實際執行搜索的方式。 Maven將從這些組ID的每個遠程存儲庫下載元數據文件(如果已下載,則將其查找到本地存儲庫中),稱為maven-metadata.xml
。 如果以我們僅有的遠程存儲庫為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/codehaus/mojo/maven-metadata.xml
。 再次,如果找不到任何內容,Maven最終會訪問http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
(注意Downloading:
登錄到mvn jetty:run
命令,准確地獲取最后兩個文件)。 如果仍然找不到任何內容,那么Maven將無法為您做任何事情,並且它將出錯:
[錯誤]在存儲庫[本地(..)中找不到在當前項目和插件組[org.mortbay.jetty,org.apache.maven.plugins,org.codehaus.mojo]中前綴為'foo'的插件。 ./.m2/存儲庫),中央( http://repo.maven.apache.org/maven2)] -> [幫助1]
這是您在這里的錯誤。 但是,如果在此搜索過程中進行了匹配,則Maven可以推斷出要使用的<artifactId>
。
現在,這意味着它具有組ID和工件ID。 最后一個難題是版本
除非在POM中明確配置,否則Maven將采用最新的版本(請參閱下一節)。 通過獲取另一個元數據文件(仍稱為maven-metadata.xml
來檢索所有可能的版本,但這一次位於存儲庫中的工件ID文件夾旁邊(與上面的文件夾ID和組ID相反)。 以Maven Clean插件為例(可以通過上述機制和mvn clean:clean
命令找到其組ID和工件ID), 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.codehaus.mojo
和org.apache.maven.plugins
組ID中查找前綴匹配項。
它確實找到了一個: Findbugs Maven插件發布在org.codehaus.mojo
組ID下; 確實,您可以在maven-metadata.xml
找到它:
<plugin>
<name>FindBugs Maven Plugin</name>
<prefix>findbugs</prefix>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
您還可以通過偷看剛推導出的findbugs-maven-plugin
下的maven-metadata.xml
文件來找到要使用的版本(在撰寫本文時為3.0.4;並注意它與您的問題的mvn findbugs:findbugs
日志中的版本)。 因此,解析成功了,然后Maven可以繼續調用此插件的findbugs
目標。
第二個例子是命令
mvn jetty:run
和以前一樣,將執行相同的解析步驟,但是在這種情況下,您會發現前綴<jetty>
不會出現在組ID org.codehaus.mojo
和org.apache.maven.plugins
任何maven-metadata.xml
中org.apache.maven.plugins
。 因此解決方案失敗,並且Maven返回您遇到的錯誤。
但是我們已經看到了如何使其工作! 我們可以在設置內添加<pluginGroup>
,以便在解析過程中也可以搜索該組ID。 Jetty Maven插件是在org.eclipse.jetty
組下發布的,如果我們窺視Maven Central中相應的maven-metadata.xml
,您會看到<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,而不是最新版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.