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

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

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

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

12 ответов


Примечание:

этот ответ относится только к Maven 2! Упомянутое LATEST и RELEASE metaversions были сброшены в Maven 3 "ради воспроизводимых сборок", около 6 лет назад. Пожалуйста, обратитесь к этому Maven 3 совместимое решение.


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

когда вы зависите от плагина или зависимости, вы можете использовать значение A версии LATEST или RELEASE. Последнее относится к последней выпущенной или моментальной версии определенного артефакта, последнего развернутого артефакта в определенном репозитории. RELEASE относится к последнему выпуску без моментальных снимков в репозитории. В общем, это не рекомендуется разрабатывать программное обеспечение, которое зависит от конкретной версии артефакта. Если вы разрабатываете программное обеспечение, вы можете использовать RELEASE или LATEST для удобства, чтобы вам не нужно было обновлять номера версий при выпуске новой версии сторонней библиотеки. Когда вы выпускаете программное обеспечение, вы всегда должны убедиться, что ваш проект зависит от конкретных версий, чтобы уменьшить вероятность того, что ваша сборка или ваш проект будут затронуты выпуском программного обеспечения не под вашим контролем. Используйте LATEST и выпускайте с осторожностью, если вообще.

посмотреть раздел синтаксиса 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>

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

<version>RELEASE</version>

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


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

поэтому обычно рекомендуется определять точные версии в выпусках. As Тим указывает, что maven-версии-плагин - удобный инструмент для обновления версий зависимостей, особенно версии: использовать-последние-версии и версии: использовать-последние-релизы целей.


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

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

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

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

  • версии: дисплей-зависимость-обновления сканирует зависимости проекта и производит отчет о тех зависимостей, которые новее доступная версия.
  • версии: дисплей-плагин-обновления сканирует Плагины проекта и создает отчет об этих плагинах которые имеют более новые версии.
  • версии: update-parent обновляет Родительский раздел проекта так что он ссылался на новый имеющиеся версии. Например, если вы используете корпоративный root POM, это цель может быть полезна, если вам нужно убедитесь, что вы используете последнюю версия корпоративного корневого пом.
  • версии: обновление-дочерние модули обновляет Родительский раздел дочерние модули проекта версия соответствует версии текущий проект. Например, если вы имейте агрегатор pom, который также родитель для проектов, которые он агрегаты и дети и родительские версии выходят из синхронизации, это mojo может помочь исправить версии дочерние модули. (Обратите внимание, что вам может потребоваться вызвать Maven с параметром-N в чтобы запустить эту цель, если ваш проект сломан так сильно, что это не удается построить из-за версии mis-match).
  • версии: lock-snapshots поиск pom для all-SNAPSHOT версии и заменяет их текущее время версия о том, что - Снимок, например - 20090327.172306-4
  • версии:разблокировка-снимки поиск pom для всех меток времени заблокированные версии snapshot и заменяет им с-снимок.
  • версии: resolve-ranges находит зависимости с использованием диапазонов версий и решает ряд конкретных версия используется.
  • версии: use-releases поиск POM для всех версий моментальных снимков которые были выпущены и заменены их с соответствующим освобождать версия.
  • версии: use-next-releases поиск pom для всех не снимка версии, которые были более новыми отпустите и замените их на следующей версии.
  • версии: используйте-next-versions поиск пом для всех версий которые были более новой версией и заменяет их следующей версией.
  • версии: commit удаляет pom.XML.файлы versionsBackup. Формы одна половина встроенного - Бедняга ... СКМ."
  • версии: revert восстанавливает pom.XML-файлы из ПФЛ.XML.файлы versionsBackup. Формы одна половина встроенного "бедного человека" СКМ."

просто подумал, что включу его для любой будущей справки.


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

<version>[1.2.3,)</version>

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


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

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

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

то есть я использую плагин versions и плагин scm для обновления зависимостей, а затем проверяю его в системе управления версиями. Да, я позволяю ... CI do SCM checkins (что вам все равно нужно сделать для плагина Maven release).

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

        <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 (что важно).

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

обновление

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

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

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

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

  1. у нас есть 20 или около того проектов в собственных репозиториях со своими собственными заданиями jenkins
  2. при выпуске используется плагин Maven release. Рабочий процесс, который охватывается в документация плагина. Плагин Maven release вроде отстой (и я добр), но он работает. Однажды мы планируем заменить этот метод чем-то более оптимальным.
  3. когда один из проектов получает выпущен Дженкинс затем запускает специальное задание мы будем называть обновление все версии задания (как Дженкинс знает, что его выпуск является сложным образом, отчасти потому, что Maven Дженкинс релиз плагин довольно дрянной, а).
  4. задание обновить все версии знает обо всех 20 проектов. На самом деле это агрегатор pom, чтобы быть конкретным со всеми проектами в разделе модулей в порядке зависимости. Дженкинс запускает наш magic groovy / bash foo, который вытащит все проекты, обновит версии до последней, а затем проверит poms (снова сделано в порядке зависимости от раздела модулей).
  5. для каждого проекта, если pom изменился (из-за изменения версии в некоторой зависимости), он проверяется, а затем мы немедленно пингуем Дженкинса для запуска соответствующее задание для этого проекта (это сохранить порядок зависимостей сборки, иначе вы находитесь во власти планировщика опроса SCM).

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

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

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


синтаксис зависимостей находится в Спецификация Требований К Версии Зависимостей документация. Вот он для полноты:

зависимостей' version элемент определяет требования к версии, используемые для вычисления эффективной версии зависимостей. Требования к версии имеют следующий синтаксис:

  • 1.0:" мягкое " требование на 1.0 (просто рекомендация, если она соответствует всем другим диапазонам для зависимость)
  • [1.0]:" трудное " требование на 1.0
  • (,1.0]: x
  • [1.2,1.3]: 1.2
  • [1.0,2.0): 1.0
  • [1.5,): x > = 1.5
  • (,1.0],[1.2,): x = 1.2; несколько наборов разделены запятыми
  • (,1.1),(1.1,): это исключает 1.1 (например, если известно не работа в сочетании с этой библиотекой)

In вашем случае, вы могли бы сделать что-то вроде <version>[1.2.3,)</version>


возможно ли, что вы зависите от версий разработки, которые, очевидно, сильно меняются во время разработки?

вместо увеличения версии версий разработки вы можете просто использовать версию моментального снимка, которую вы перезаписываете при необходимости, что означает, что вам не придется изменять тег версии при каждом незначительном изменении. Что-то вроде 1.0-SNAPSHOT...

но, может быть, вы пытаетесь достичь чего-то другого ;)


кто когда-либо использует последнее, пожалуйста, убедитесь, что у вас есть-U в противном случае последний снимок не будет вытащен.

mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// pull the latest snapshot for my-foo from all repositories

к тому времени, когда этот вопрос был задан, были некоторые перегибы с диапазонами версий в maven, но они были разрешены в более новых версиях maven. В этой статье очень хорошо показано, как работают диапазоны версий и рекомендации, чтобы лучше понять, как maven понимает версии: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855


правда, даже в 3.x он все еще работает, удивительно, что проекты строятся и развертываются. Но ключевое слово LATEST/RELEASE вызывает проблемы в m2e и eclipse повсюду, также проекты зависят от зависимости, которая развернута через последнюю/RELEASE, не распознает версию.

Это также вызовет проблему, если вы попытаетесь определить версию как свойство и ссылаться на нее еще где.

Так что вывод использовать версии-maven-плагин если вы можете.


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

одно решение будет использовать версии-maven-плагин. Например, можно объявить свойство:

<properties>
    <myname.version>1.1.1</myname.version>
</properties>

и добавьте плагин versions-maven в файл pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>versions-maven-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <properties>
                    <property>
                        <name>myname.version</name>
                        <dependencies>
                            <dependency>
                                <groupId>group-id</groupId>
                                <artifactId>artifact-id</artifactId>
                                <version>latest</version>
                            </dependency>
                        </dependencies>
                    </property>
                </properties>
            </configuration>
        </plugin>
    </plugins>
</build>

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

mvn versions:update-properties validate

если есть версия новее, чем 1.1.1, он скажет вам:

[INFO] Updated ${myname.version} from 1.1.1 to 1.3.2

мое решение в maven 3.5.4, используйте nexus, в eclipse:

<dependency>
    <groupId>yilin.sheng</groupId>
    <artifactId>webspherecore</artifactId>
    <version>LATEST</version> 
</dependency>

затем в Eclipse: atl + F5 и выберите force update of snapshots/release

это работает для меня.


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

но как разработчик, я не буду рекомендовать этот тип практики. Почему?

ответ на вопрос почему уже дан Паскаль Thivent в комментарии к вопросу

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

Я буду рекомендовать этот тип практики:

<properties>
    <spring.version>3.1.2.RELEASE</spring.version>
</properties>

<dependencies>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

</dependencies>

легко поддерживать и легко отлаживать. Вы можете обновить POM в кратчайшие сроки.