Как мне сказать Maven использовать последнюю версию зависимости? - PullRequest
721 голосов
/ 27 августа 2008

В Maven зависимости обычно устанавливаются так:

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

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

Ответы [ 12 ]

696 голосов
/ 23 июля 2009

ПРИМЕЧАНИЕ:

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


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

Когда вы зависите от плагина или зависимости, вы можете использовать значение версии LATEST или RELEASE. ПОСЛЕДНИЙ относится к последней выпущенной версии или версии моментального снимка конкретного артефакта, самого последнего развернутого артефакта в определенном хранилище. RELEASE относится к последнему выпуску без моментальных снимков в хранилище. В целом, не рекомендуется разрабатывать программное обеспечение, которое зависит от неспецифической версии артефакта. Если вы разрабатываете программное обеспечение, вы можете использовать RELEASE или LATEST для удобства, чтобы вам не приходилось обновлять номера версий при выпуске нового выпуска сторонней библиотеки. Когда вы выпускаете программное обеспечение, вы всегда должны следить за тем, чтобы ваш проект зависел от конкретных версий, чтобы уменьшить шансы вашей сборки или проекта повлиять на выпуск программного обеспечения, который не находится под вашим контролем. Используйте 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>

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


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

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

350 голосов
/ 23 июля 2009

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

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

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

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

  • версии: display-dependency-updates сканирует зависимости проекта и производит отчет о тех зависимости, которые имеют более новые Доступные версии.
  • версии: display-plugin-updates сканирует плагины проекта и выдает отчет об этих плагинах которые имеют более новые версии доступны.
  • версии: update-parent обновляет родительский раздел проекта так, что он ссылается на новейшие доступная версия. Например, если вы используете корпоративный корневой POM, это цель может быть полезна, если вам нужно убедитесь, что вы используете последнюю версию версия корпоративного рута POM.
  • версии: update-child-modules обновляет родительский раздел дочерние модули проекта, поэтому версия соответствует версии текущий проект. Например, если вы есть агрегатор пом, который также родитель для проектов, которые это агрегаты и дети и родительские версии не синхронизированы, это Моджо может помочь исправить версии дочерние модули. (Обратите внимание, что вам может понадобиться вызывать Maven с опцией -N в Чтобы запустить эту цель, если ваш проект сломан так сильно, что он не может построить из-за версии MIS-матч).
  • версии: lock-snapshots ищет в pom все -SNAPSHOT версии и заменяет их текущая версия отметки времени этого -SNAPSHOT, например, -20090327.172306-4
  • версии: unlock-snapshots ищет помп для всех временных меток заблокированные снимки версий и замен их с -SNAPSHOT.
  • версии: разрешения-диапазоны находит зависимости с использованием диапазонов версий и разрешает диапазон для конкретного используемая версия.
  • версии: use-release ищет в pom все версии -SNAPSHOT которые были выпущены и заменяет их с соответствующим выпуском версия.
  • версии: use-next-Releases ищет в pom все не-SNAPSHOT версии, которые были более новыми освободить и заменить их версия следующего выпуска.
  • версии: use-next-version ищет в pom все версии которые были более новой версией и заменяет их следующей версией.
  • версии: commit удаляет файлы pom.xml.versionsBackup. формы половина встроенного "Бедного человека" СКМ».
  • версии: вернуть восстанавливает файлы pom.xml из Файлы pom.xml.versionsBackup. формы половина встроенного "Бедного человека" СКМ».

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

165 голосов
/ 27 августа 2008

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

<version>[1.2.3,)</version>

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

77 голосов
/ 10 января 2012

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

Я заставляю Хадсона / Дженкинса делать следующее для каждой сборки:

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

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

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

        <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>

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

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

Обновление

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

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

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

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

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

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

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

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

30 голосов
/ 22 июля 2015

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

Элемент

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

  • 1.0: «мягкое» требование к 1.0 (просто рекомендация, если оно соответствует всем другим диапазонам для зависимости)
  • [1.0]: жесткое требование на 1.0
  • (,1.0]: х <= 1,0 </li>
  • [1.2,1.3]: 1,2 <= x <= 1,3 </li>
  • [1.0,2.0): 1,0 <= x <2,0 </li>
  • [1.5,): x> = 1,5
  • (,1.0],[1.2,): х <= 1,0 или х> = 1,2; несколько наборов разделены запятыми
  • (,1.1),(1.1,): это исключает 1.1 (например, если известно, что работать в сочетании с этой библиотекой)

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

14 голосов
/ 27 августа 2008

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

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

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

6 голосов
/ 03 августа 2015

Кто когда-либо использовал ПОСЛЕДНЮЮ, пожалуйста, убедитесь, что у вас есть -U, иначе последний снимок не будет извлечен.

mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// pull the latest snapshot for my-foo from all repositories
6 голосов
/ 03 апреля 2015

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

4 голосов
/ 26 июня 2015

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

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

Итак, вывод: используйте version-maven-plugin , если можете.

2 голосов
/ 08 мая 2017

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

Одним из способов решения этой проблемы было бы использование version-maven-plugin . Например, вы можете объявить свойство:

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

и добавьте version-maven-plugin в ваш файл 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
...