Как указать Maven использовать последнюю версию зависимости?
Я работаю с проектом на Maven и постоянно обновляю зависимости. Обычно зависимости настраиваются следующим образом:
<dependency>
<groupId>wonderful-inc</groupId>
<artifactId>dream-library</artifactId>
<version>1.2.3</version>
</dependency>
Однако, если вы работаете с библиотеками, которые имеют частые релизы, постоянное обновление тега <version>
может быть довольно утомительным. Существует ли способ указать Maven всегда использовать последнюю доступную версию из репозитория?
5 ответ(ов)
Если вы используете LATEST, убедитесь, что у вас есть флаг -U, иначе последняя версия (snapshot) не будет загружена.
Пример команды для загрузки самой последней версии:
mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// загрузит последнюю snapshot-версию my-foo из всех репозиториев
Не забывайте про флаг -U, чтобы избежать проблем с обновлением.
На момент постановки этого вопроса в Maven имелись некоторые проблемы с диапазонами версий, однако они были устранены в более новых версиях Maven. Эта статья очень хорошо объясняет, как работают диапазоны версий и содержит лучшие практики для лучшего понимания того, как Maven обрабатывает версии: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855
Я не согласен с мнением, что всегда стоит использовать самую последнюю версию. Есть множество причин, почему это может быть оправдано, особенно в условиях непрерывного развертывания (у нас иногда бывает до 5 релизов в день) и когда не хочется заморачиваться с многоуровневыми проектами.
Что я делаю, так это настраиваю Hudson/Jenkins для выполнения следующих команд на каждой сборке:
mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true
Здесь я использую плагины versions и scm для обновления зависимостей, а затем фиксирую изменения в системе контроля версий. Да, я позволяю CI выполнять фиксации в SCM (что обязательно для использования плагина мaven 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 и последнюю релизную версию для релизных сборок. Ваши сборки также будут воспроизводимыми.
Обновление
Я заметил комментарии с вопросами о подробностях этого рабочего процесса. Хочу отметить, что мы больше не используем этот метод, так как плагин maven versions имеет ряд ошибок и в целом обладает недостатками.
Недостаток заключается в том, что для корректной работы плагина versions все существующие версии должны быть доступны. То есть плагин не сможет обновить зависимости до последней версии, если не найдет текущее упоминание о версии в pom-файле. Это довольно раздражает, так как мы часто очищаем старые версии ради экономии места на диске.
На самом деле, нужен отдельный инструмент от maven для изменения версий (чтобы не зависеть от корректной работы pom файла). Я написал такой инструмент на Bash. Скрипт обновляет версии, как плагин и фиксирует pom обратно в систему контроля версий. Он также работает примерно в 100 раз быстрее, чем mvn versions plugin. К сожалению, он не оптимизирован для публичного использования, но если будет интерес, я мог бы сделать его доступным на gists или GitHub.
Что касается рабочего процесса, вот что мы делаем:
- У нас есть около 20 проектов в отдельных репозиториях с собственными заданиями Jenkins.
- При релизе используется плагин maven release. Рабочий процесс описан в документации к плагину. Плагин мaven release не идеален (и я мягко выражаюсь), но он работает. В будущем мы планируем заменить этот метод на что-то более оптимальное.
- Когда один из проектов выпускается, Jenkins запускает специальное задание, которое мы назвали "обновить все версии" (как Jenkins понимает, что это релиз, - вопрос сложный, partly because the Maven Jenkins release plugin is pretty flaky).
- Задание "обновить все версии" знает обо всех 20 проектах. Это фактически агрегатор pom, который включает все проекты в разделе модулей в порядке зависимости. Jenkins запускает наш волшебный скрипт на groovy/bash, который собирает все проекты, обновляет версии до последних и фиксирует pom файлы (опять же в порядке зависимости в соответствии с разделом модулей).
- Для каждого проекта, если pom изменился (из-за изменения версии одной из зависимостей), это фиксируется, и мы сразу же вызываем Jenkins, чтобы запустить соответствующее задание для этого проекта (это делается для сохранения порядка сборки зависимости, иначе вы будете зависеть от планировщика SCM).
На мой взгляд, стоит разделять инструменты для релизов и автоматического обновления версий от общего процесса сборки.
Возможно, вы подумаете, что Maven имеет свои недостатки из-за упомянутых проблем, но реализовать это было бы довольно сложно с помощью инструмента, который не имеет декларативного, легкого для парсинга расширяемого синтаксиса (например, XML).
На самом деле, мы добавляем пользовательские XML-атрибуты через пространства имен, чтобы помочь подсказать bash/groovy скриптам (например, "не обновлять эту версию").
Вы, возможно, зависите от версий для разработки, которые явно часто меняются в процессе. Вместо того чтобы увеличивать номер версии для этих релизов, вы могли бы использовать версию-снэпшот, которую можно перезаписывать по мере необходимости. Это избавит вас от необходимости менять тег версии при каждом мелком изменении. Например, можно использовать 1.0-SNAPSHOT...
Но, возможно, вы пытаетесь достичь чего-то другого 😉
Ваша проблема, вероятно, связана с загрузкой зависимости в Eclipse при использовании Maven и Nexus. Я предлагаю следующее решение:
<dependency>
<groupId>yilin.sheng</groupId>
<artifactId>webspherecore</artifactId>
<version>LATEST</version>
</dependency>
После добавления этой зависимости в ваш файл pom.xml
, выполните обновление проекта в Eclipse. Для этого используйте сочетание клавиш Alt + F5
и выберите опцию Force update of snapshots/releases
.
Это должно помочь вам успешно загрузить нужные зависимости. Надеюсь, это решит вашу проблему! Если будут вопросы, не стесняйтесь спрашивать.
Как добавить локальные JAR-файлы в Maven-проект?
Как создать исполняемый JAR-файл с зависимостями с использованием Maven?
Как работают сервлеты? Инстанцирование, сессии, общие переменные и многопоточность
Возможные значения конфигурации hbm2ddl.auto в Hibernate и их назначение
Что такое PECS (Producer Extends Consumer Super)?