2008-08-27 3 views
623

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

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

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

+134

Я действительно не рекомендую эту практику (и не использую диапазоны версий) ради повышения воспроизводимости. Сборка, которая начинает неожиданно завершаться по неизвестной причине, более раздражает, чем вручную обновляет номер версии. – 2009-09-17 22:52:32

+0

@Martin Мне известно о соглашении xyz-SNAPSHOT, но я думал о библиотеках, которые выпущены в окончательных версиях в репозиторий (т. Е. Идет из dream-library-1.2.3.jar в dream-library-1.2.4. банку и т. д.). – 2008-08-27 16:50:04

+8

@PascalThivent Ручное обновление номера версии в pom - это боль, если вы делаете непрерывные релизы.Я использую плагин версий в сочетании с плагином scm, чтобы пройти мимо этого (см. Мой ответ). – 2012-01-09 21:24:50

ответ

618

Примечание:

Этот ответ относится к Maven 2 только! Указанные LATEST и RELEASE метаверсии have been dropped in Maven 3 "for the sake of reproducible builds", более 6 лет назад. См. Это Maven 3 compliant solution.

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

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

Для получения более подробной информации см. POM Syntax section of the Maven book. Или увидит этот документ на Dependency Version Ranges, где:

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

Вот пример, иллюстрирующий различные варианты. В репозитории 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> 

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

Объявляет точную версию (всегда будет решать 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-профиль» из Maven super POM. Вы можете сделать это либо с «-Prelease профиля» или «-DperformRelease = истина»


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

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

14

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

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

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

159

Пожалуйста, обратите внимание на this page (раздел «Зависимость от версии Ranges»). Что вы можете сделать, это что-то вроде

<version>[1.2.3,)</version> 

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

+0

По какой-то причине этот вариант не сработал для меня, он выбрал версию внутри диапазона, но не самую новую. – sorin 2012-09-12 14:29:08

+3

Возможно, вам понадобится более пристальное изучение того, как Maven сравнивает номера версий - если вы не соответствуете строгой схеме, Maven сравнивает как строки, а не числа. – 2013-02-25 13:19:24

290

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

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

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

Следующих другие целей:

  • версия: дисплей-зависимости обновление сканируют зависимости проекта, и создает отчет о тех зависимости, которые имеют новую версии.
  • версии: display-plugin-updates сканирует плагины проекта и создает отчет о тех плагинах , которые имеют более новые версии.
  • версии: update-parent обновляет родительский раздел проекта, поэтому указывает, что он ссылается на новейшую доступную версию. Например, если вы используете корпоративный POM, этот может быть полезен, если вам нужно убедиться, что вы используете последнюю версию корпоративного корневого POM .
  • версия: обновление-ребенок-модули обновляет родительский раздел из дочерних модулей проекта, поэтому версия совпадает с версией текущего проекта . Например, если у вас есть агрегатор POM, который также родительские для проектов, которые он агрегатов и дети и родительских версий рассинхронизации, это харизмы может помочь исправить версии дочерних модулей. (Обратите внимание, что вам может понадобиться вызывать Maven с опцией -N в , чтобы выполнить этот гол, если ваш проект сломан настолько плохо, что он не может построить из-за версии mis-match).
  • версия: замок-снимка Отыскивает POM для всех -snapshot версий и заменяет их с версией текущей временной метки этого -snapshot, например, -20090327.172306-4
  • версии: разблокировка моментальных снимков Отыскивает POM для всех Отметка времени запертых версий моментальных снимков и заменяет их -snapshot.
  • версии: диапазоны разрешений находит зависимости, использующие диапазоны версий, и разрешает диапазон до указанной версии .
  • версия: использование-релизы Отыскивает POM для всех версий -snapshot , которые были выпущены и заменяет их с соответствующей версией релиза .
  • версии: использование-некст-релизы Отыскивает POM для всех не SNAPSHOT версий, которые были новее релиз и заменяет их следующей версии .
  • версии: use-next-versions ищет pom для всех версий , которые были более новой версией, и заменяет их следующей версией.
  • версии: commit удаляет файлы pom.xml.versionsBackup. Формы одна половина встроенного «Плохого человека SCM».
  • версии: revert восстанавливает файлы pom.xml из файлов pom.xml.versionsBackup. Формы одна половина встроенного «Плохого человека SCM».

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

70

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

Что я могу сделать, это сделать Hudson/Jenkins сделать следующее для каждой сборки:

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

То есть я использую версию плагина и ВСМ плагин для обновления зависимостей, а затем проверить его в системе управления версиями. Да, я разрешаю моим 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 (что важно).

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

Update

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

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

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

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

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

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

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

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

5

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

3

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

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

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

22

Синтаксис зависимостей находится в документации Dependency Version Requirement Specification. Здесь он для полноты:

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

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

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

6

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

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

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

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

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

и добавьте версии-Maven-плагин к файлу п:

<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 
Смежные вопросы