gpt4 book ai didi

java - Maven 插件前缀解析是如何工作的?为什么它解析 "findbugs"而不是 "jetty"?

转载 作者:行者123 更新时间:2023-12-02 08:26:49 25 4
gpt4 key购买 nike

我正在使用 Maven 进行一些测试并意识到我可以执行 findbugs Findbugs 插件的目标,而无需将插件添加到 POM 文件中。另一方面,当我需要运行 run 时Jetty 插件的目标,我被迫将插件添加到 POM 文件或构建失败。

  • 为什么 Jetty 需要在 POM 中进行配置而 Findbugs 不需要?
  • Maven 如何知道要执行哪些 Findbug(假设我们必须使用相同名称但不同组 ID 的插件)?

  • 当我运行第一个命令时,构建成功,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的Plugin Prefix Resolution。这是一项功能,它使用户能够通过使用其前缀来调用特定 Maven 插件的目标。当您在命令行上直接调用目标时,您可以使用以下全功能形式:

    mvn my.plugin.groupId:foo-maven-plugin:1.0.0:bar

    这将调用具有坐标 bar(以 my.plugin.groupId:foo-maven-plugin:1.0.0 的形式)的 Foo Maven 插件的目标 groupId:artifactId:version。它运行良好,但有点冗长。以更简单的方式调用这个目标会很好,而不指定所有这些坐标。 Maven 通过为插件分配前缀使这成为可能,因此您可以引用此前缀而不是整个坐标,使用:

    mvn foo:bar
    ^^^ ^^^
    | |
    prefix |
    |
    goal

    这个前缀是如何确定的?

    您可以为每个 Maven 插件定义一个前缀。这对应于用于识别它的简单名称:

    The conventional artifact ID formats to use are:

    • maven-${prefix}-plugin - for official plugins maintained by the Apache Maven team itself (you must not use this naming pattern for your plugin, see this note for more informations)
    • ${prefix}-maven-plugin - for plugins from other sources

    If your plugin's artifactId fits this pattern, Maven will automatically map your plugin to the correct prefix in the metadata stored within your plugin's groupId path on the repository.



    换句话说,如果你的插件的 artifact id 被命名为 foo-maven-plugin ,Maven 会自动给它分配一个前缀 foo 。如果您不想要这个默认分配,您仍然可以在 maven-plugin-plugin 及其 goalPrefix 参数的帮助下配置您自己的。

    Maven 如何将前缀映射到插件?

    在命令中

    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 fooorg.mortbay.jettyorg.apache.maven.plugins 中查找前缀为 org.codehaus.mojo 的插件。

    第二步是实际执行搜索的方式。 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 就无能为力了,它会报错:

    [ERROR] No plugin found for prefix 'foo' in the current project and in the plugin groups [org.mortbay.jetty, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (.../.m2/repository), central (http://repo.maven.apache.org/maven2)] -> [Help 1]



    这是你在这里的错误。但是,如果在此搜索过程中进行了一次匹配,则 Maven 可以推断出要使用的 <artifactId>

    它现在意味着它具有组 ID 和 Artifact ID。最后一块拼图是版本

    将使用哪个版本?

    Maven 将采用最新的可用版本,除非在 POM 中明确配置(参见下一节)。所有可能的版本都是通过获取另一个元数据文件来检索的,仍然称为 maven-metadata.xml ,但这次与存储库中的 artifact id 文件夹一起存在(与上面的相反,它与 group id 一起存在)。以 Maven Clean 插件为例(通过上述机制和 mvn clean:clean 命令可以找到它的组 ID 和 Artifact 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 will select as version <release> 版本,代表插件的最新发布版本。如果该标签不存在,它将选择 <latest>,代表插件、发行版或快照的最新版本。可能会发生两个标签都不存在的情况,在这种情况下,Maven will select the first release, or the first snapshot for lack of a release<version> 元素列表。

    如果仍然失败,则 Maven 再也无法为您做任何事情,无法推断出版本并且出现错误。不过这不太可能发生。我们现在已经收集了组 ID、 Artifact ID 和版本;是时候最终调用我们插件的 bar 目标了。

    我的配置有什么问题?

    如上所述,Maven 在 Activity 远程存储库中查找某些预定义的组 ID,以查找具有给定前缀的匹配项。随着命令

    mvn findbugs:findbugs

    Maven 以 findbugs 前缀开始搜索。由于我们的配置在我们的设置中没有任何 <pluginGroup>,Maven 会查看 org.codehaus.mojoorg.apache.maven.plugins 组 ID 以查找前缀匹配。

    它确实找到了一个: Findbugs Maven Plugin 发布在 org.codehaus.mojo 组 ID 下;事实上,你可以找到它 in the 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;并注意它如何与您问题的 mvn findbugs:findbugs 日志中的版本完全匹配)来找到将要使用的版本)。所以解析成功了,接下来Maven就可以继续调用这个插件的 findbugs 目标了。

    第二个例子是命令

    mvn jetty:run

    和以前一样,会发生相同的解析步骤,但在这种情况下,您会发现前缀 <jetty> 没有出现在组 ID maven-metadata.xmlorg.codehaus.mojo 的任何 org.apache.maven.plugins 中。因此解析失败,Maven 返回您遇到的错误。

    但我们已经看到了如何让它发挥作用!我们可以在我们的设置中添加一个 <pluginGroup>,以便在解析过程中也可以搜索到这个组 ID。 Jetty Maven Plugin 发布在组 ID org.eclipse.jetty 下,如果我们查看相应的 maven-metadata.xml in Maven Central ,您会看到 <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 版本,而不是最新版本。

    关于java - Maven 插件前缀解析是如何工作的?为什么它解析 "findbugs"而不是 "jetty"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40205664/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com