Maven устанавливает стратегию посредничества зависимостей как самую новую, а не ближайшую

Могу ли я настроить Maven для выбора «самой новой» зависимости от конфликта, а не «ближайшей»?

«Самая новая» используется по умолчанию в Ivy и других разумных менеджерах зависимостей, см. http://ant.apache.org/ivy/history/2.2.0/settings/conflict-managers.html

Я считаю, что «ближайшая» стратегия редко бывает тем, что мне нужно.

Я использую Maven 3.3.3, но при необходимости могу поменять версию.

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

(См. документацию Maven в разделе "Посредничество зависимостей". ")


person Rich    schedule 10.12.2015    source источник
comment
Если вы говорите, что редко не хотите, это одно мнение. Насколько я знаю, нет простого способа изменить это поведение... Что вы можете сделать, так это предоставить патч, который изменяет поведение в Maven Core... Чтобы обнаружить такие вещи, вы можете использовать правила принудительного исполнения для выявления таких ситуаций. ..   -  person khmarbaise    schedule 10.12.2015
comment
Это обсуждение о предыдущей попытке добавить эту функциональность в Maven стоит прочитать.   -  person heenenee    schedule 30.03.2017
comment
Спасибо, @heenee. Теперь я понимаю, почему Maven вообще не развивался за последние 10 лет или около того, он кажется полностью умирающим. Может быть, я попытаюсь переключить свой проект на SBT, который имеет новейшее разрешение конфликтов зависимостей, может использовать Maven deps и поддерживается IntelliJ.   -  person Rich    schedule 30.03.2017
comment
@Rich Я выделил наиболее важные части обсуждения в ответ. Обычно я не отвечаю на вопросы отрицательно, но в данном случае я чувствую, что это оправдано. При наследовании исходного кода я обычно счастлив, если это проект Maven, потому что сборка легко понятна (в немалой степени потому, что Maven развивается так медленно), однако обычно я начинаю свои собственные новые проекты с Gradle. Вы должны использовать то, что лучше всего подходит для вас и вашей команды; если это SBT, то дерзайте.   -  person heenenee    schedule 02.04.2017


Ответы (2)


Можно ли настроить Maven для автоматического использования «новейшей» версии зависимости вместо «ближайшей» при разрешении конфликтов версий?

Нет, вы не можете настроить стратегию посредничества зависимостей Maven на что-либо, кроме ближайшего.

Добавление настраиваемых стратегий посредничества зависимостей было предлагалось ранее, но в конечном итоге от него отказались, потому что это предложение включало изменение POM XSD, чего не происходило уже много лет.

Почему Maven использует ближайшую стратегию по умолчанию?

Стратегия ближайшего подходит Maven по двум причинам:

  1. Простое преодоление отдельных конфликтов: для любой конкретной конфликтующей зависимости вы можете указать ее версию в своем собственном POM, и эта версия станет ближайшей.
  2. Воспроизводимые сборки: Диапазоны версий в любом месте графа зависимостей могут привести к невозможности воспроизведения сборок. Стратегия посредничества «самая новая» усилит негативное влияние диапазонов версий на воспроизводимость сборки.

Но мне действительно нужна другая стратегия посредничества зависимостей. Что я могу сделать?

Это ваши лучшие варианты:

  1. Создать расширение Maven: использование «ближайшей» стратегии определяется NearestVersionSelector в MavenRepositorySystemUtils. Вы можете создать собственное расширение Maven, определяющее ваше собственное VersionSelector, который реализует выбранную вами стратегию, затем в методе afterSessionStart вашего расширения замените DependencyGraphTransformer сеанса тем, который использует ваш собственный VersionSelector.
  2. Переход на другой инструмент сборки: очевидно.
person heenenee    schedule 02.04.2017
comment
Спасибо. Может ли плагин сборки не переопределить это поведение? Это даст возможность изменить это без изменения POM XSD. - person Rich; 03.04.2017
comment
Этот комментарий предполагает, что плагин сборки не может изменять зависимости: Maven 3.x внес изменения в разрешение зависимостей, что делает невозможным оптимальную работу этого плагина. В Maven 3.x все зависимости разрешаются до запуска фаз жизненного цикла, что делает невозможным загрузку и установку подключаемым модулем внешних зависимостей до того, как Maven разрешит зависимости проекта. github.com/UniversalMediaServer/ - person Rich; 03.04.2017
comment
Для чего этот класс? github.com/apache/maven/blob/master/maven-compat/src/main/java/ - person Rich; 03.04.2017
comment
@Rich, этот класс предназначен для Maven 2. - person heenenee; 03.04.2017
comment
@Rich, как вы процитировали, плагины не выполняются в то время, когда можно изменить стратегию разрешения конфликтов, поэтому плагин для этого нежизнеспособен. Однако вы можете сделать расширение Maven, поэтому я соответствующим образом обновил свой ответ. - person heenenee; 03.04.2017
comment
Стоит выделить: AbstractMavenLifecycleParticipant.afterSessionStart не вызывается при объявлении сборки <extension> или через плагин <extensions>, должен находиться в ${maven.home}/lib/ext или ${maven.projectBasedir}/.mvn/extensions.xml. Только в afterSessionStart можно изменять session.getRepositorySession(), к моменту вызова afterProjectsRead он доступен только для чтения. - person earcam; 06.10.2018
comment
Стоит отметить, что самая новая означает самую старую версию, которая удовлетворяет всем зависимостям. Это не самая новая версия или что-то в этом роде. Это не должно вызывать невоспроизводимые сборки в случае простых зависимостей. Для диапазонов Maven может просто вернуться к исходному поведению. Очень обидно. - person proski; 13.07.2019

Вы также можете использовать правило "requireUpperBoundDeps" для Maven "enforcer », который не будет напрямую реализовывать политику разрешения конфликтов «новейшие победы», но будет обеспечивать, чтобы конечный результат был таким же. Вам нужно будет вручную добавить правила транзитивной зависимости <exclusions> или <dependencyManagement> в ваш POM, чтобы выбрать самую новую зависимость в каждом конфликте, но, по крайней мере, тогда вы будете уверены, что конечным результатом будет «самая новая победа».

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <id>enforce</id>
        <configuration>
          <rules>
            <requireUpperBoundDeps />
          </rules>
        </configuration>
        <goals>
          <goal>enforce</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
person Rich    schedule 04.04.2017