Как работает разрешение префикса плагина Maven? Почему он разрешает "findbugs", но не"jetty"?

я делал некоторое тестирование с помощью Maven и понял, что могу выполнить findbugs цель плагина Findbugs без добавления плагина в файл POM. С другой стороны, когда мне нужно было запустить run цель плагина Jetty, я был вынужден добавить плагин в файл POM или сборка не удалась.

  • почему причал нуждался в конфигурации в POM, а Findbugs нет?
  • как Maven знает, какие Findbugs выполнять (предположим, мы должны плагины с то же имя, но другой идентификатор группы)?

когда я запускаю первую команду, сборка выполняется успешно без каких-либо изменений в файле 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>

1 ответов


что такое приставка и зачем она нам нужна?

вы только что столкнулись с Разрешение Префикса Плагина для Maven. Это функция, которая позволяет пользователю вызывать цели конкретного плагина 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. Это соответствует простому имени, используемому для его идентификации:

обычные форматы идентификаторов артефактов для использования:

  • maven-${prefix}-plugin - для официальных плагинов, поддерживаемых самой командой Apache Maven (вы не должны использовать этот шаблон именования для своего плагина, см. эту заметку для получения дополнительной информации)
  • ${prefix}-maven-plugin - плагинов из других источников

если artifactId вашего плагина соответствует этому шаблону, Maven автоматически сопоставит ваш плагин с правильным префиксом в метаданных, хранящихся в вашем путь groupId плагина в репозитории.

другими словами, если идентификатор артефакта вашего плагина называется 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, какой идентификатор группы он должен учитывать, когда вы используете префикс в команде. По умолчанию, и в дополнение к группам, указанным в настройках, Maven также ищет идентификаторы группы org.apache.maven.plugins и org.codehaus.mojo. Он ищет те, по умолчанию, после тех, которые вы настроено в настройках. Поэтому с конфигурацией выше и командой mvn foo:bar, Maven будет искать плагин, имеющий префикс foo внутри группы id org.mortbay.jetty, org.apache.maven.plugins и org.codehaus.mojo.

второй шаг заключается в том, как этот поиск фактически выполняется. Maven будет загружать файлы метаданных (или просматривать их в локальном репозитории, если они уже загружены), называемый maven-metadata.xml, из каждого удаленного хранилища в этих идентификаторах групп. Если мы возьмем пример, где только удаленный репозиторий у нас есть Maven Central, Maven сначала загрузит http://repo1.maven.org/maven2/org/mortbay/jetty/maven-metadata.xml, и посмотрите внутри этого файла, если у нас есть что-то mapping foo. Обратите внимание, как идентификатор группы был преобразован в структуру каталогов в удаленном репозитории. Структура этого файла метаданных:

<metadata>
  <plugins>
    <plugin>
      <name>Some Awesome Maven Plugin</name>
      <prefix>somePrefix</prefix>
      <artifactId>some-maven-plugin</artifactId>
    </plugin>
  </plugins>
</metadata>

если ни один из содержат <prefix> это равно тому, который мы указали (foo), Maven продолжит работу со следующим идентификатором группы, нажав 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 больше ничего не может сделать для вас, и это будет ошибка:

[ошибка] не найден плагин для префикса " foo " в текущем проекте и в группах плагинов [org.mortbay.jetty, org.апаш.знаток.plugins, org.codehaus.mojo] доступно из репозитории [местное (.../.m2 / repository), центральный (http://repo.maven.apache.org/maven2)] -> [помогите 1]

это ошибка, которую вы здесь имеете. Однако, если во время этого поиска было сделано одно совпадение, Maven может вывести <artifactId> использовать.

теперь это означает, что у него есть идентификатор группы и идентификатор артефакта. Последняя часть головоломки-это версия

какая версия будет использоваться?

Maven будет принимать последние один доступный, если явно не настроен в POM (см. Следующий раздел). Все возможные версии извлекаются путем извлечения другого файла метаданных, все еще называемого maven-metadata.xml, но на этот раз живет рядом с папкой идентификатора артефакта в репозитории (в отличие от вышеприведенных, где он был рядом с идентификатором группы). Возьмем пример плагина Maven Clean (чей идентификатор группы и идентификатор артефакта будут найдены с помощью вышеуказанного механизма и команды 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 будет выбрать в качестве версии the <release> версия, которая представляет собой новейшую версию плагина. Если этого тега нет, он выберет <latest> которые представляют собой последнюю версию плагина, выпуска или моментального снимка. Может случиться так, что обоих тегов нет, и в этом случае Maven будет выбрать первый выпуск, или первый снимок из-за отсутствия выпуска, список <version> элементы.

если это все еще не удается, Maven больше ничего не может сделать для вас, версия не может быть выведена и это ошибки. Хотя это вряд ли произойдет. Теперь мы собрали идентификатор группы, идентификатор артефакта и версию; время, чтобы, наконец, вызвать bar цель нашего плагина.

в чем проблема с моей конфигурации?

как сказано выше, Maven ищет в определенных предопределенных идентификаторах групп внутри активных удаленных репозиториев для поиска соответствует заданному префиксу. С командой

mvn findbugs:findbugs

Maven начинает поиск с findbugs префикс. Так как наша конфигурация не имеет каких-либо <pluginGroup> в наших настройках Maven смотрит в org.codehaus.mojo и org.apache.maven.plugins идентификатор группы для префикса.

и он находит один:Maven С Помощью FindBugs Плагин опубликовано под org.codehaus.mojo group 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 на момент написания этой статьи; и обратите внимание, как он точно соответствует версии в mvn findbugs:findbugs журналы вашего вопроса). Таким образом, разрешение удалось, а затем Maven может продолжать вызывать findbugs цель этого плагина.

второй пример-команда

mvn jetty:run

как и раньше, те же шаги разрешения бывает, но, в этом случае, вы узнаете, что приставка <jetty> не появляется ни в одном из maven-metadata.xml для идентификаторов групп org.codehaus.mojo и org.apache.maven.plugins. Таким образом, разрешение не удается, и Maven возвращает ошибку, которая у вас есть.

но мы видели, как это работает! Мы можем добавить <pluginGroup> внутри наших настроек, так что этот идентификатор группы также можно искать во время разрешения. The Jetty Maven Плагин публикуется под идентификатором группы org.eclipse.jetty и если мы заглянем в соответствующий maven-metadata.xml в Maven Central, вы увидите, что <prefix>jetty</prefix> есть. Таким образом, исправление просто: просто определите этот новый идентификатор группы для поиска в настройках:

<pluginGroups>
  <pluginGroup>org.eclipse.jetty</pluginGroup>
</pluginGroups>

теперь Maven также рассмотрит этот идентификатор группы и сопоставит 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> в настройках: идентификатор группы был записан в POM. Кроме того, он гарантирует, что версия 9.2.11.v20150529 будет использоваться вместо последнего.