Як мені сказати Maven використовувати останню версію залежності?


788

У Мейвен залежності зазвичай встановлюються так:

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

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


@Martin Я знаю конвенцію xyz-SNAPSHOT, але я думав про бібліотеки, які випускаються в остаточних версіях до сховища (тобто, переходячи від бібліотеки мрій-1.2.3.jar до бібліотеки мрій-1.2.4.jar , і так далі).
Андерс Сандвіг

176
Я дійсно не рекомендую цю практику (а також не використовувати діапазони версій) задля створення відтворюваності. Побудова, яка починає раптово виходити з ладу з невідомих причин, є набагато більше дратівливою, ніж оновлення номера версії вручну.
Паскаль Thivent

12
@PascalThivent Оновлення номера випуску в пам’яті - це біль, якщо ви робите безперервні випуски. Я використовую плагін версій у поєднанні з scm плагіном, щоб пройти це (див. Мою відповідь).
Адам Гент

4
@PascalThivent Обидва дратують, але по-іншому. Я хотів би вибрати між обома залежними від моєї ситуації, і не змушувати його використовувати, тому що хтось інший вирішив, що це буде краще.
piegames

Відповіді:


745

ПРИМІТКА:

Ця відповідь стосується лише Maven 2! Згадані LATESTта RELEASEметаверсії були скинуті в Maven 3 "заради відтворюваних будівель" понад 6 років тому. Будь ласка, зверніться до цього сумісного рішення Maven 3 .


Якщо ви завжди хочете використовувати новітню версію, Maven має два ключові слова, які можна використовувати як альтернативу діапазонам версій. Ви повинні використовувати ці параметри з обережністю, оскільки ви більше не контролюєте плагіни / залежності, якими користуєтесь.

Якщо ви залежите від плагіна або залежності, ви можете використовувати значення версії LATEST або RELEASE. ОСТАННЯ посилається на останню випущену або знімку версії певного артефакту, останнього розгорнутого артефакту у певному сховищі. 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>

Оголосіть версію як ЗВ'ЯЗКУВАННЯ (буде дозволено до 1.1.1) (видалено з Maven 3.x):

<version>RELEASE</version>

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


Варто підкреслити, що будь-який підхід, який дозволяє Maven вибирати версії залежностей (ОСТАННІ, RELEASE та діапазони версій), може залишати вас відкритими для створення тимчасових питань, оскільки пізніші версії можуть мати різну поведінку (наприклад, плагін залежності раніше змінив типовий режим значення від істинного до помилкового, з заплутаними результатами).

Тому, як правило, найкраще визначити точні версії у випусках. Як вказує відповідь Тіма, плагін maven-version-модуля - це зручний інструмент для оновлення версій залежностей, зокрема версій: use-latest-version and version: use-latest-reitions .


76
Привіт Річ! Він з'являється RELEASE і НОВІТНІ маркери версії не більше не підтримуються в Maven 3.x .
Паскаль Thivent

16
Ця депресія, здається, застосовується лише до плагінів, а не до звичайних залежностей, якщо я правильно розумію документ
Mond Raymond

9
@RichSeller hey Rich; Я витратив на це трохи часу, перш ніж зрозумів, що це більше не доступне в Maven 3.0;) Чи можете ви змінити відповідь, щоб вона почалася з оновлення, де було б сказано про зневіреність Maven 3.0? Дякую купу!
Мікель

6
Я вважаю, що хорошим балансом було б заблокувати основну версію, але отримати останню незначну (або виправлену) версію (залежно від того, що застосовується для виправлення помилок лише у штучній виправі, від якої ви залежите). З поточним синтаксисом це здається можливим лише в такому діапазоні (примітка: починається дужками і закінчується паронами):[1.1,2.0)
Amr Mostafa

2
FWIW ... оновлено посилання на нотатки сумісності Maven3
dyodji

384

Тепер я знаю, що ця тема є давньою, але читаючи питання та відповідь, що надає ОП, здається, плагін Maven Versions міг би бути найкращою відповіддю на його запитання:

Зокрема, такі цілі можуть бути корисними:

  • версії: use-latest- version шукає пом для всіх версій, які були більш новою версією, і замінює їх на останню версію.
  • версії: use-latest-rells шукає помпо для всіх версій, які не є SNAPSHOT, які були більш новою версією та замінює їх на останню версію версії.
  • версії: властивості update-властивості оновлення властивостей, визначених у проекті, щоб вони відповідали останній доступній версії конкретних залежностей. Це може бути корисно, якщо набір залежностей повинен бути заблокований до однієї версії.

Також передбачені інші цілі:

  • версії: оновлення залежності від показника відображає залежність проекту та створює звіт про ті залежності, у яких доступні новіші версії.
  • версії: display-plugin-updates сканує плагіни проекту та створює звіт з тих плагінів, у яких доступні новіші версії.
  • версії: update-parent оновлює батьківський розділ проекту, щоб він посилався на останню доступну версію. Наприклад, якщо ви використовуєте корпоративний кореневий POM, ця мета може бути корисною, якщо вам потрібно переконатися, що ви використовуєте останню версію корпоративного кореневого POM.
  • версії: update-дочірні модулі оновлює батьківський розділ дочірніх модулів проекту, щоб версія відповідала версії поточного проекту. Наприклад, якщо у вас є помпок агрегатора, який також є батьківським для проектів, які він агрегує, і дочірні та батьківські версії виходять із синхронізації, це mojo може допомогти виправити версії дочірніх модулів. (Зверніть увагу, що вам може знадобитися викликати Maven за допомогою параметра -N, щоб виконати цю мету, якщо ваш проект зламаний настільки сильно, що він не може побудувати через невідповідність версії).
  • версії: lock-snapshots здійснює пошук пам’яті для всіх версій -SNAPSHOT та замінює їх поточною версією часової позначки цієї -SNAPSHOT, наприклад -20090327.172306-4
  • версії: unlock-snapshots здійснює пошук пам’яті для всіх зафіксованих часових позначок версій знімка та замінює їх на -SNAPSHOT.
  • версії: резоль-діапазони знаходять залежності, використовуючи діапазони версій, і вирішує діапазон до конкретної версії, яка використовується.
  • версії: use- release шукає пом для всіх версій -SNAPSHOT, які були випущені, і замінює їх відповідною версією релізу.
  • версії: use-next- release шукає пом для всіх версій, які не є SNAPSHOT, які були більш новою версією, і замінює їх на наступну версію.
  • версії: use-next- version шукає пом для всіх версій, які були більш новою версією, і замінює їх на наступну версію.
  • версії: commit видаляє файли pom.xml.versionsBackup. Формує половину вбудованого "Бідного чоловіка СКМ".
  • версії: відновлення відновлює файли pom.xml з файлів pom.xml.versionsBackup. Формує половину вбудованого "Бідного чоловіка СКМ".

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


10
У цьому контексті, яка різниця між "випуском" та "версією".
Бен Ноланд

1
@BenNoland, я вважаю, що різниця в цьому випадку полягає в тому, що наступна версія може не потребувати артефакту випуску. Напр., Артефакт з версією 1.0.0-SNAPSHOT, 1.0.0 та 1.0.1-SNAPSHOT, а також пам’ятне посилання на 1.0.0-SNAPSHOT, версії: наступні версії та версії: наступні версії будуть дозволені до 1.0.0 , тоді як версії: останні версії та версії: останні випуски будуть вирішувати до 1.0.1-SNAPSHOT та 1.0.0 відповідно.
Ryan Beesley

1
Ви можете вирішити деякі невизначеності між версіями / випусками / знімками в цій дуже приємній таблиці тут: goo.gl/iDq6PK
Ev0oD

1
Друк усіх можливих і непов’язаних цілей не корисний.
MariuszS

2
Я думаю, що версії: використання останніх версій вирішує більшість проблем ОП.
Alex R

172

Перегляньте цю сторінку (розділ "Діапазони версій залежності"). Що ви, можливо, захочете зробити щось подібне

<version>[1.2.3,)</version>

Ці діапазони версій реалізовані в Maven2.


Чомусь цей варіант не працював для мене, він вибрав версію всередині діапазону, але не найновішу.
sorin

4
Ви можете детальніше ознайомитись з тим, як Maven порівнює номери версій - якщо ви не відповідаєте суворій схемі, Maven порівнює як рядки, а не числа.
Thorbjørn Ravn Andersen

Ця сторінка знаходиться на Codehaus і описує себе як речі, "які ще не реалізовані для Maven 2.0" ... Сама документація Maven нічого не говорить про діапазони версій. Я щось пропускаю? Коли були введені діапазони версій? Де вони описані в офіційній документації?
Шеннон

1
Ви помиляєтеся, діапазон версій означає, що всі версії в порядку від 1.2.3 до вище. Це зовсім не остання версія.
MariuszS

@sorin У вас, можливо, були інші залежності у вашому проекті, які також залежать від артефакту? Спробуйте mvn dependency:tree -Dverboseце зрозуміти. Це може пояснити несподівану версію.
Євген Бересовський

83

На відміну від інших, я думаю, що є багато причин, чому ви завжди хочете останню версію. Особливо, якщо ви робите безперервне розгортання (у нас іноді є 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 є помилковим і в цілому є суттєвим недоліком.

Це недоліки, оскільки для запуску плагіна версій для коригування версій всі існуючі версії повинні існувати, щоб пом працював правильно. Тобто плагін версій не може оновлюватись до останньої версії нічого, якщо він не може знайти версію, на яку посилається у пам’яті. Це насправді досить дратує, оскільки ми часто чистимо старі версії з міркувань дискового простору.

Дійсно, вам потрібен окремий інструмент від maven для коригування версій (так що ви не залежите від файлу pom, щоб правильно запустити). Я написав такий інструмент низькою мовою, якою є Баш. Сценарій буде оновлювати версії, такі як плагін версії, і перевірити пом назад у контролі джерела. Він також працює на 100 разів швидше, ніж плагін версій mvn. На жаль, він не написаний таким чином для публічного користування, але якщо люди зацікавлені, я можу зробити так і покласти його в суть або github.

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

  1. У нас є близько 20 проектів у власних сховищах із власними роботами у джинкінах
  2. Коли ми випускаємо плагін Maven release, використовується плагін. Робочий процес цього описується в документації на плагін. Плагін випуску Maven висмоктує (і я добрий), але він працює. Одного разу ми плануємо замінити цей метод чимось більш оптимальним.
  3. Коли один із проектів випускає jenkins, тоді він виконує спеціальну роботу, ми називаємо роботу з оновленнями всіх версій (як відомо, jenkins знає, що її випуск частково є складним способом, тому що плагін для випуску Maven jenkins також досить хиткий).
  4. Завдання для оновлення всіх версій знає про всі 20 проектів. Фактично, агрегатор повинен бути специфічним для всіх проектів у розділі модулів у порядку залежності. Дженкінс запускає наше чарівне грошове / баш-фу, що дозволить усім проектам оновити версії до найновіших, а потім перевірити піс (що знову робиться в порядку залежності залежно від розділу модулів).
  5. Для кожного проекту, якщо пом. Змінили (через зміну версії в якійсь залежності), він реєструється, і ми негайно пінг-джинкінів, щоб виконати відповідне завдання для цього проекту (це зберегти порядок залежності залежності побудови, інакше ти на розсуд планувальника опитування SCM).

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

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

Насправді ми додаємо власні атрибути XML через простори імен, щоб допомогти натякнути bash / groovy сценарії (наприклад, не оновлювати цю версію).


5
Дякуємо, що у відповідь включили мотивацію (безперервне розгортання).
Девід Дж. Лішевський

10
Я думаю, що важливим моментом тут є те, що будується, можна відтворити за допомогою цього методу, тоді як при використанні діапазонів версій або-ПОСЛІДНИХ, вони не є!
marc.guenther

Я хотів би відрегулювати рішення за допомогою зовнішнього інструменту, який вносить зміни до проекту pom перед тим, як запустити збірку. Ми також використовуємо цей підхід, оскільки плагін версій-діапазону властивий помилкам, наприклад, враховуючи дати та не тільки версії.
Даніель Гайдук

37

Синтаксис залежностей знаходиться в документації щодо специфікації вимог версії залежності . Ось це для повноти:

versionЕлемент залежностей визначає вимоги до версії, що використовується для обчислення ефективної версії залежності. Вимоги до версії мають такий синтаксис:

  • 1.0: Вимога "soft" на 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>


15

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

Замість того, щоб збільшувати версію розробок розробок, ви можете просто використати версію знімків, яку ви перезаписуєте, коли це необхідно, а це означає, що вам не доведеться міняти тег версій при кожній незначній зміні. Щось на кшталт 1.0-SNAPSHOT ...

Але, можливо, ви намагаєтесь домогтися чогось іншого;)


7

Хто коли-небудь використовує ОСТАННІ, будь ласка, переконайтеся, що у вас є -У інакше не зніметься останній знімок.

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

навіть використовуючи -UI я отримуюCouldn't download artifact: Failed to resolve version for com.app:common:jar:LATEST
Роберт

7

До того часу, як було поставлено це питання, існували деякі перегини з діапазоном версій Maven, але вони були вирішені в нових версіях Maven. Ця стаття дуже добре фіксує, як працюють діапазони версій та найкращі практики, щоб краще зрозуміти, як Maven розуміє версії: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855


2
Хоча це теоретично може відповісти на питання, бажано було б сюди включити істотні частини відповіді та надати посилання для довідки.
Карл Ріхтер

6

Правда навіть у 3.x вона все ще працює, напрочуд, що проекти будують та розгортають. Але ключове слово "ОСТАННЕ / ЗВ'ЯЗКУ", що спричиняє проблеми в m2e та затемнення в усьому місці, ТАКОЖ проекти залежать від залежності, яка розгорнута через ПОСЛІДНІЙ / ЗВ'ЯЗКУ не вдається розпізнати версію.

Це також спричинить проблему, якщо ви спробуєте визначити версію як властивість та посилати її ще кудись.

Отже, висновок - використовувати версії-maven-плагін, якщо можете.


5

Іноді ви не хочете використовувати діапазони версій, тому що, здається, вони "повільні" для вирішення ваших залежностей, особливо коли на місці є безперервна доставка та є версії версій - переважно під час важких розробок.

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

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

і додайте версії-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

3

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

Але як розробник я не рекомендую цей тип практик. ЧОМУ?

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

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

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

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


якщо ви використовуєте версії-maven-плагін, збірка все одно відтворюється. Оновлення версії maven можна виконати в окремому комітеті (як видно з моєї відповіді, ви повинні вказати окрему мету, вона просто не відбувається магічним чином у складанні).
Маркон

1

МОЙ розчин у Maven 3.5.4, використовуйте Nexus, у затемненні:

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

потім у затемненні:, atl + F5і виберітьforce update of snapshots/release

це працює для мене.


Не буду працювати в командному рядку, хоча з міркувань, які вище вказані в різних постах. Багатьом з нас доводиться відповідати автоматизованим складанням, і тому наші POM повинні працювати, коли вони працюють в командному рядку, а не тільки в Eclipse.
bigbadmouse

Я використовую maven 3.5.4, і отримав це під час використання "останнього": або ОСТАННЕ, або ЗВ'ЯЗКУВАННЯ (обидва вони застаріли) @ рядок 154, стовпець 13
Леонардо Леонардо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.