web-dev-qa-db-ja.com

Mavenプラグインのプレフィックス解決はどのように機能しますか? 「findbugs」は解決するが「jetty」は解決しないのはなぜですか?

Mavenを使用していくつかのテストを行っていて、POMファイルにプラグインを追加せずにFindbugsプラグインのfindbugs目標を実行できることに気付きました。一方、Jettyプラグインのrunゴールを実行する必要があるとき、プラグインをPOMファイルに追加するように強制された、またはビルドが失敗しました。

  • Findbugsが不要であるのに、JettyがPOMでの設定を必要としたのはなぜですか?
  • MavenはどのFindbugsを実行するかをどのように知るのですか(同じ名前で異なるグループ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] -----------------------------------------------------------------------

しかし、2番目を実行すると、次のようになります。

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>
13
Jachk E

プレフィックスとは何ですか、なぜ必要なのですか?

Mavenの プラグインプレフィックス解決 に遭遇しました。これは、ユーザーがプレフィックスを使用して特定のMavenプラグインの目標を呼び出すことができる機能です。コマンドラインで目標を直接呼び出す場合、次の完全な機能を備えた形式を使用できます。

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

これにより、座標my.plugin.groupId:foo-maven-plugin:1.0.0groupId:artifactId:versionの形式)を持つFoo Mavenプラグインの目標barが呼び出されます。うまくいきますが、少し冗長です。これらのすべての座標を指定せずに、この目標をより簡単な方法で呼び出すとよいでしょう。 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>

これが行うことは、コマンドでプレフィックスを使用しているときに考慮すべきグループIDをMavenに伝えることです。デフォルトでは、設定で指定されたグループに加えて、 MavenはグループID org.Apache.maven.pluginsorg.codehaus.mojo も検索します。設定で構成したものの後、それらのデフォルトのものを検索します。したがって、上記の構成とmvn foo:barのコマンドを使用すると、MavenはグループID org.mortbay.jettyorg.Apache.maven.plugins、およびorg.codehaus.mojo内で接​​頭辞fooを持つプラグインを探します。

2番目のステップは、検索が実際に実行される方法です。 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は http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml を押して次のグループIDを続行します。繰り返しますが、何も見つからない場合、Mavenは最終的に http://repo1.maven.org/maven2/org/Apache/maven/plugins/maven-metadata.xml をヒットします(Downloading:mvn jetty:runコマンドに記録され、最後の2つのファイルを正確に取得します)。それでも見つからない場合は、Mavenでできることはもうありません。エラーになります。

[エラー]現在のプロジェクトおよびプラグイングループ[org.mortbay.jetty、org.Apache.maven.plugins、org.codehaus.mojo]のプレフィックス 'foo'のリポジトリがリポジトリ[ローカル(.. ./.m2/repository)、central( http://repo.maven.Apache.org/maven2)] -> [ヘルプ1]

これはここにあるエラーです。ただし、この検索中に1つの一致が見つかった場合、Mavenは使用する<artifactId>を推測できます。

これは、グループIDとアーティファクトIDを持っていることを意味します。パズルの最後のピースはバージョンです

どのバージョンが使用されますか?

Mavenは、POMで明示的に構成されていない限り、最新のものを使用します(次のセクションを参照)。可能性のあるすべてのバージョンは、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.codehaus.mojoおよびorg.Apache.maven.pluginsグループIDを調べます。

Findbugs Maven Plugin は、org.codehaus.mojoグループIDの下で公開されます。確かに、あなたはそれを見つけることができます in 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 目標を呼び出すことができます。

2番目の例はコマンドです

mvn jetty:run

前と同じ解決手順が行われますが、この場合、グループID <jetty>およびmaven-metadata.xmlorg.codehaus.mojoのいずれにも接頭辞org.Apache.maven.pluginsが表示されないことがわかります。そのため、解決は失敗し、Mavenはユーザーが持っているエラーを返します。

しかし、私たちはそれを機能させる方法を見てきました!設定内に<pluginGroup>を追加して、解決時にこのグループIDも検索できるようにすることができます。 Jetty Mavenプラグイン はグループID 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が使用されるようにします。

39
Tunaki