Maven, разрешающая версии зависимостей

Если две зависимости модуля имеют общую зависимость, но имеют разные версии, указанные в их поместьях, какая версия используется при построении модуля?

Например

        Artifact-A
        /       \
       /         \
      /           \
Artifact-B      Artifact-C
      \           /
 1.6.0 \         / 1.8.0
        \       /
        Artifact-D

Аналогично в сценарии, подробно описанном ниже, какая версия Artifact-C использует Artifact-A?

    Artifact-A
        |      \
        |       |
        |       |
    Artifact-B  | 1.60.0
        |       |
 1.62.0 |       |
        |      /
    Artifact-C

Если вы могли бы предоставить или ссылку на краткое объяснение того, как maven разрешает эти версии.

Ответ 1

См. Введение в механизм зависимостей:

С транзитивными зависимостями график включенных библиотек может быстро расти достаточно большим. По этой причине есть некоторые дополнительные функции, которые ограничивают, какие зависимости включены:

  • Согласование зависимости - это определяет, какая версия зависимости будет использоваться, когда встречаются несколько версий артефакта. В настоящее время Maven 2.0 поддерживает только "ближайшее определение", что означает, что он будет использовать версию ближайшей зависимости от вашего проекта в дереве зависимостей. Вы всегда можете гарантировать версию, объявив ее явно в своем проекте POM. Обратите внимание: если две версии зависимостей находятся на одной и той же глубине в дереве зависимостей, пока Maven 2.0.8 не будет определен, какой из них будет побежден, но поскольку Maven 2.0.9 это порядок в объявлении, который считается: первый объявление выигрывает.
    •   
    • "ближайшее определение" означает, что используемая версия будет самой близкой к вашему проекту в дереве зависимостей, например. если зависимости для A, B и C определены как A → B → C → D 2.0 и A → E → D 1.0, тогда D 1.0 будет использоваться при построении A, поскольку путь от A до D через E короче. Вы можете явно добавить зависимость от D 2.0 в A, чтобы принудительно использовать D 2.0  

Это означает, что для вашего первого примера (и запуска Maven 2.0.9), если артефакт B объявлен как зависимость в перед артефактом C следующим образом:

<dependency>
   <groupId>groupB</groupId>
   <artifactId>projectB</artifactId>
</dependency>
<dependency>
   <groupId>groupC</groupId>
   <artifactId>projectC</artifactId>
</dependency>

тогда выбирается зависимость D, объявленная в проекте B.