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

703

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

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

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

  • 0
    @Martin Я знаю о соглашении xyz-SNAPSHOT, но я думал о библиотеках, выпущенных в окончательных версиях для репозитория (то есть переходя от dream-library-1.2.3.jar к dream-library-1.2.4.jar , и так далее).
  • 162
    Я действительно не рекомендую эту практику (ни использование диапазонов версий) ради воспроизводимости сборки. Сборка, которая начинает неожиданно завершаться сбоем по неизвестной причине, намного раздражает, чем обновление номера версии вручную.
Показать ещё 2 комментария
Теги:
maven
dependencies
maven-2
maven-metadata

12 ответов

627
Лучший ответ

ЗАМЕТКА:

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


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

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

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

<version>RELEASE</version>

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


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

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

  • 72
    Привет Рич! Похоже, маркеры версий RELEASE и LATEST больше не поддерживаются в Maven 3.x.
  • 15
    Это оскорбление, похоже, относится только к плагинам, а не к обычным зависимостям, если я правильно понимаю документ
Показать ещё 5 комментариев
320

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

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

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

Также предоставляются следующие цели:

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

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

  • 8
    В этом контексте какая разница между «релизом» и «версией».
  • 1
    @BenNoland, я считаю, что разница в этом случае заключается в том, что в следующей версии может не быть артефакт релиза. Например, передаются артефакт версии 1.0.0-SNAPSHOT, 1.0.0 и 1.0.1-SNAPSHOT и ссылка pom на 1.0.0-SNAPSHOT, версии: следующие версии и версии: следующие выпуски будут разрешаться до 1.0.0 тогда как версии: последние версии и версии: последние выпуски будут преобразовываться в 1.0.1-SNAPSHOT и 1.0.0 соответственно.
Показать ещё 9 комментариев
171

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

<version>[1.2.3,)</version>

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

  • 0
    По какой-то причине этот вариант не работал для меня, он выбрал версию внутри диапазона, но не самую новую.
  • 4
    Возможно, вы захотите поближе взглянуть на то, как Maven сравнивает номера версий - если вы не соответствуете строгому шаблону, Maven сравнивает как строки, а не числа.
Показать ещё 3 комментария
72

В отличие от других, я думаю, есть много причин, почему вы всегда можете найти последнюю версию. В частности, если вы делаете непрерывное развертывание (иногда у нас есть как 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>

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

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

Обновление

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

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

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

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

  • У нас есть около 20 проектов в их собственных хранилищах со своими собственными работами jenkins.
  • Когда мы выпускаем плагин релиза maven. Рабочий процесс описан в документации к плагину. Плагин релиза maven отстой (и я добрый), но он работает. Однажды мы планируем заменить этот метод чем-то более оптимальным.
  • Когда один из проектов будет выпущен, jenkins запускает специальное задание, которое мы будем называть обновлением всех версий (как известно, его выпуск является сложным способом из-за того, что плагин релиза maven jenkins также довольно дерьмовый).
  • Обновление всех версий заданий знает обо всех 20 проектах. Фактически, агрегатор pom должен быть конкретным со всеми проектами в разделе модулей в порядке зависимости. Дженкинс управляет нашей магией groovy/bash foo, которая заставит все проекты обновить версии до последней версии, а затем проведет посты (снова сделанные в порядке зависимости на основе раздела модулей).
  • Для каждого проекта, если pom изменился (из-за изменения версии в некоторой зависимости), он проверяется, а затем мы сразу же ping jenkins запускаем соответствующее задание для этого проекта (это необходимо для сохранения порядка зависимостей сборки, иначе вы по милости планировщика опроса SCM).

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

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

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

  • 5
    Спасибо за включение мотивации (непрерывного развертывания) в ваш ответ.
  • 10
    Я думаю, что здесь важно то, что сборки воспроизводимы этим методом, тогда как при использовании диапазонов версий или -LATEST это не так!
29

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

Элемент

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

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

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

14

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

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

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

6

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

mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// pull the latest snapshot for my-foo from all repositories
  • 0
    даже при использовании -UI я получаю Couldn't download artifact: Failed to resolve version for com.app:common:jar:LATEST
5

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

  • 0
    Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки.
3

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

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

Таким образом, вывод заключается в использовании versions-maven-plugin, если вы можете.

2

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

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

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

и добавьте версии-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
1

МОЕ решение в 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

меня устраивает.

  • 0
    Не будет работать в командной строке, хотя по причинам, изложенным выше в различных сообщениях. Многие из нас должны соответствовать автоматизированным сборкам, поэтому наши POM должны работать при запуске из командной строки, а не только в Eclipse.
  • 0
    Я использую maven 3.5.4 и получил это при использовании 'latest': LATEST или RELEASE (оба они устарели) @ строка 154, столбец 13
0

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

Но как разработчик, я не буду рекомендовать этот тип практики. ЗАЧЕМ?

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

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

Я рекомендую этот тип практики:

<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 в кратчайшие сроки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню