Вопрос-ответ

How do I tell Maven to use the latest version of a dependency?

Как мне сообщить Maven использовать последнюю версию зависимости?

В Maven зависимости обычно настраиваются следующим образом:

<dependency>
<groupId>wonderful-inc</groupId>
<artifactId>dream-library</artifactId>
<version>1.2.3</version>
</dependency>

Теперь, если вы работаете с библиотеками с частыми выпусками, постоянное обновление тега <version> может несколько раздражать. Есть ли какой-либо способ указать Maven всегда использовать последнюю доступную версию (из репозитория)?

Переведено автоматически
Ответ 1

ПРИМЕЧАНИЕ:

Упомянутые LATEST и RELEASE метаверсии были удалены из-за зависимостей плагинов в Maven 3 "ради воспроизводимых сборок" более 6 лет назад. (Они по-прежнему отлично работают для обычных зависимостей.) Чтобы узнать о зависимостях плагинов, пожалуйста, обратитесь к этому Maven 3 совместимому решению.


Если вы всегда хотите использовать самую новую версию, в Maven есть два ключевых слова, которые вы можете использовать в качестве альтернативы диапазонам версий. Вам следует использовать эти параметры с осторожностью, поскольку вы больше не контролируете используемые вами плагины / зависимости.


Когда вы зависите от плагина или зависимости, вы можете использовать значение a version, равное LATEST или RELEASE . LATEST относится к последней выпущенной версии или моментальному снимку определенного артефакта, самому последнему развернутому артефакту в конкретном репозитории. RELEASE относится к последнему выпуску в репозитории без моментального снимка. В общем, не рекомендуется разрабатывать программное обеспечение, которое зависит от неспецифической версии артефакта. Если вы разрабатываете программное обеспечение, вы можете использовать RELEASE или LATEST для удобства, чтобы вам не приходилось обновлять номера версий при выпуске нового выпуска библиотеки сторонних производителей. При выпуске программного обеспечения вы всегда должны убедиться, что ваш проект зависит от определенных версий, чтобы снизить вероятность того, что на вашу сборку или ваш проект повлияет выпуск программного обеспечения, находящийся не под вашим контролем. Используйте ПОСЛЕДНЮЮ версию и RELEASE с осторожностью, если вообще используете.


Смотрите Раздел синтаксиса POM в книге Maven для получения более подробной информации. Или смотрите этот документ о диапазонах версий зависимостей, где:


  • Квадратная скобка ( [ & ] ) означает "закрыто" (включительно).

  • Скобка ( ( & ) ) означает "открытый" (эксклюзивный).

Вот пример, иллюстрирующий различные варианты. В репозитории Maven com.foo:my-foo содержит следующие метаданные:

<?xml version="1.0" encoding="UTF-8"?><metadata>
<groupId>com.foo</groupId>
<artifactId>my-foo</artifactId>
<version>2.0.0</version>
<versioning>
<release>1.1.1</release>
<versions>
<version>1.0</version>
<version>1.0.1</version>
<version>1.1</version>
<version>1.1.1</version>
<version>2.0.0</version>
</versions>
<lastUpdated>20090722140000</lastUpdated>
</versioning>
</metadata>

Если требуется зависимость от этого артефакта, у вас есть следующие параметры (конечно, можно указать другие диапазоны версий, просто здесь показаны соответствующие):

Объявите точную версию (всегда будет соответствовать 1.0.1):

<version>[1.0.1]</version>

Объявить явную версию (всегда будет разрешаться до 1.0.1, если не произойдет коллизии, когда Maven выберет соответствующую версию):

<version>1.0.1</version>

Объявить диапазон версий для всех 1.x (в настоящее время будет разрешен до 1.1.1):

<version>[1.0.0,2.0.0)</version>

Объявить открытый диапазон версий (будет разрешен до 2.0.0):

<version>[1.0.0,)</version>

Объявите версию как ПОСЛЕДНЮЮ (разрешится до 2.0.0) (удалено из maven 3.x)

<version>LATEST</version>

Объявите версию как RELEASE (разрешится до 1.1.1) (удалено из maven 3.x):

<version>RELEASE</version>

Обратите внимание, что по умолчанию ваши собственные развертывания обновят запись "latest" в метаданных Maven, но для обновления записи "release" вам необходимо активировать "release-profile" из Maven super POM. Вы можете сделать это либо с помощью "-Prelease-profile", либо "-DperformRelease = true"


Стоит подчеркнуть, что любой подход, позволяющий Maven выбирать версии зависимостей (ПОСЛЕДНЮЮ, ВЫПУСК и диапазоны версий), может привести к проблемам со временем сборки, поскольку более поздние версии могут вести себя по-другому (например, плагин зависимостей ранее изменил значение по умолчанию с true на false, что приводит к путаным результатам).

Поэтому, как правило, хорошей идеей является определение точных версий в релизах. Как следует из ответа Тима, плагин maven-versions является удобным инструментом для обновления версий зависимостей, особенно целей versions:use-latest-versions и versions:use-latest-releases.

Ответ 2

Теперь я знаю, что эта тема старая, но, прочитав вопрос и предоставленный OP ответ, кажется, что плагин Maven Versions на самом деле мог бы быть лучшим ответом на его вопрос:

В частности, могут быть полезны следующие цели:


  • versions:use-latest-versions выполняет поиск в pom всех версий, которые были более новой версией, и заменяет их последней версией.

  • versions:use-latest-releases выполняет поиск в pom всех версий, отличных от SNAPSHOT, которые были более новой версией, и заменяет их последней версией выпуска.

  • версии: обновление-свойства обновляет свойства, определенные в проекте, чтобы они соответствовали последней доступной версии конкретных зависимостей. Это может быть полезно, если все наборы зависимостей должны быть привязаны к одной версии.

Также предусмотрены следующие другие цели:


  • версии: отображение зависимостей-обновления сканирует зависимости проекта и создает отчет о тех зависимостях, для которых доступны более новые версии.

  • versions:display-plugin-updates сканирует плагины проекта и создает отчет о тех плагинах, у которых доступны более новые версии.

  • версии: обновление-parent обновляет родительский раздел проекта, чтобы он ссылался на самую последнюю доступную версию. Например, если вы используете корпоративный root POM, эта цель может быть полезна, если вам нужно убедиться, что вы используете последнюю версию корпоративного root POM.

  • versions:update-дочерние модули обновляет родительский раздел дочерних модулей проекта, чтобы версия соответствовала версии текущего проекта. Например, если у вас есть pom-агрегатор, который также является родительским для проектов, которые он агрегирует, и дочерние и родительские версии не синхронизированы, этот моджо может помочь исправить версии дочерних модулей. (Обратите внимание, что вам может потребоваться вызвать Maven с параметром -N, чтобы выполнить эту задачу, если ваш проект поврежден настолько сильно, что он не может быть собран из-за несоответствия версий).

  • версии: lock-snapshots выполняет поиск в pom всех версий SNAPSHOT и заменяет их текущей версией с отметкой времени этого SNAPSHOT, например -20090327.172306-4

  • versions: unlock-snapshots выполняет поиск в pom всех версий snapshots с заблокированными временными метками и заменяет их на -SNAPSHOT .

  • versions:resolve-ranges находит зависимости, используя диапазоны версий, и преобразует диапазон в конкретную используемую версию.

  • versions:use-releases выполняет поиск в pom всех версий SNAPSHOT, которые были выпущены, и заменяет их соответствующей версией выпуска.

  • versions:use-next-releases выполняет поиск в pom всех версий, отличных от SNAPSHOT, которые были более новым выпуском, и заменяет их версией следующего выпуска.

  • versions:use-next-versions выполняет поиск в pom всех версий, которые были более новой версией, и заменяет их следующей версией.

  • versions:commit удаляет файлы резервной копии pom.xml.versionsBackup. Формирует половину встроенного "Poor Man's SCM".

  • versions:revert восстанавливает pom.xml файлы из файлов pom.xml.versionsBackup. Формирует половину встроенного "Poor Man's SCM".

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

Ответ 3

Пожалуйста, взгляните на эту страницу (раздел "Диапазоны версий зависимостей"). Возможно, вам захочется сделать что-то вроде

<version>[1.2.3,)</version>

Эти диапазоны версий реализованы в Maven2.

Ответ 4

В отличие от других, я думаю, есть много причин, по которым вам может всегда хотеться последняя версия. Особенно, если вы выполняете непрерывное развертывание (иногда у нас выходит около 5 релизов в день) и не хотите выполнять многомодульный проект.

Что я делаю, так это заставляю Hudson / Jenkins выполнять следующее для каждой сборки:

mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true

То есть я использую плагин versions и плагин scm для обновления зависимостей, а затем проверяю это в системе управления версиями. Да, я разрешаю моему CI выполнять проверки SCM (которые вы в любом случае должны выполнять для плагина maven release).

Вы захотите настроить плагин versions так, чтобы обновлять только то, что вы хотите:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includesList>com.snaphop</includesList>
<generateBackupPoms>false</generateBackupPoms>
<allowSnapshots>true</allowSnapshots>
</configuration>
</plugin>

Я использую плагин release для создания релиза, который обрабатывает -SNAPSHOT и проверяет, существует ли релизная версия -SNAPSHOT (что важно).

Если вы сделаете то, что делаю я, вы получите последнюю версию для всех сборок snapshot и последнюю версию release для сборок release. Ваши сборки также будут воспроизводимыми.

Обновить

Я заметил несколько комментариев, в которых спрашиваются некоторые особенности этого рабочего процесса. Я скажу, что мы больше не используем этот метод, и основная причина, по которой плагин maven versions содержит ошибки и вообще по своей сути несовершенен.

Это ошибка, потому что для запуска плагина versions для настройки версий должны существовать все существующие версии, чтобы pom работал правильно. То есть плагин versions не может обновиться до последней версии чего-либо, если он не может найти версию, указанную в pom. На самом деле это довольно раздражает, поскольку мы часто очищаем старые версии из соображений экономии места на диске.

На самом деле вам нужен отдельный инструмент от maven для настройки версий (чтобы вы не зависели от корректной работы файла pom). Я написал такой инструмент на простом языке, который называется Bash. Скрипт обновит версии, как плагин version, и вернет pom обратно в систему управления версиями. Он также работает в 100 раз быстрее, чем плагин mvn versions. К сожалению, это написано не для публичного использования, но если людям интересно, я мог бы сделать это таким образом и поместить в gist или github.

Возвращаясь к рабочему процессу, поскольку в некоторых комментариях задавался вопрос об этом, это то, что мы делаем:


  1. У нас есть около 20 проектов в их собственных репозиториях с их собственными заданиями jenkins

  2. При выпуске используется плагин maven release. Рабочий процесс этого описан в документации к плагину. Плагин maven release в некотором роде отстой (и я добрый), но он действительно работает. Однажды мы планируем заменить этот метод чем-то более оптимальным.

  3. Когда один из проектов будет выпущен, дженкинс запустит специальное задание, которое мы назовем заданием обновить все версии (то, как дженкинс узнает о его выпуске, является сложным способом, отчасти потому, что плагин maven jenkins release также довольно дерьмовый).

  4. Задание обновить все версии знает обо всех 20 проектах. На самом деле это pom-агрегатор, который конкретизирует все проекты в разделе модули в порядке зависимости. Дженкинс запускает наш волшебный groovy / bash foo, который извлекает все проекты, обновляет версии до последней, а затем проверяет pom (опять же, в порядке зависимости, основанном на разделе модулей).

  5. Для каждого проекта, если pom изменился (из-за изменения версии в какой-либо зависимости), он проверяется, а затем мы немедленно отправляем запрос дженкинсу на выполнение соответствующего задания для этого проекта (это делается для сохранения порядка построения зависимостей, в противном случае вы находитесь во власти планировщика опроса SCM).

На данный момент я придерживаюсь мнения, что в любом случае неплохо иметь release и автоматическую версию отдельным инструментом от вашей общей сборки.

Теперь вы можете подумать, что maven в некотором роде отстой из-за перечисленных выше проблем, но на самом деле это было бы довольно сложно с инструментом сборки, который не имеет декларативного, простого для разбора расширяемого синтаксиса (он же XML).

Фактически мы добавляем пользовательские атрибуты XML через пространства имен, чтобы помочь подсказать скриптам bash / groovy (например, не обновлять эту версию).

java maven