Разрешение зависимостей Maven (противоречие)



допустим, у меня есть четыре проекта:




  • проект A (имеет зависимость от B и D)

  • проект B (имеет зависимость от D)

  • Проект C (имеет зависимость от D)

  • Проект D


в этом случае, если я запускаю проект A, Maven правильно разрешит зависимость до D. Если я правильно понимаю, что Maven всегда принимает зависимость с кратчайшим путем. Поскольку D является прямой зависимостью от A, он будет использоваться скорее затем D, который указан в Б.



но теперь предположим, что это structre:




  • проект A (имеет зависимость от B и C)

  • проект B (имеет зависимость от D)

  • Проект C (имеет зависимость от D)

  • Проект D


в этом случае пути к разрешению D имеют одинаковую глубину. Что происходит, так это то, что у Maven будет конфликт. Я знаю, что можно сказать Maven, что он должен исключить зависимости. Но мой вопрос в том, как решить такого рода проблемы. Я имею в виду, что в реальном приложении у вас есть много depenendcies и, возможно, много конфликтов.



является ли лучшим практическим решением действительно исключить материал или есть другие возможные решения для этого? Мне очень трудно справиться с тем, когда я внезапно получаю исключение ClassNotFound, потому что некоторые версии изменились, что заставило Maven принять зависимость differend. Конечно, зная этот факт, становится немного легче предположим, что проблема заключается в конфликте зависимостей.



Я использую Maven 2.1-SNAPSHOT.

1020   5  

5 ответов:

maven способ разрешения подобных ситуаций заключается в том, чтобы включить <dependencyManagement> раздел в корневом pom вашего проекта, где вы указываете, какая версия какой библиотеки будет использоваться.

EDIT:

<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>foo</groupId>
        <artifactId>bar</artifactId>
        <version>1.2.3</version>
    </dependency>
   </dependencies>
</dependencyManagement>

теперь независимо от того, какая версия библиотеки foo:bar запрашивается зависимостью, версия 1.2.3 всегда будет использоваться для этого проекта и всех подпроектов.

ссылки:

Maven может обрабатывать обе ситуации без каких-либо конфликтов. Конфликты будут существовать, когда требуются две версии транзитивной зависимости. Элемент ClassNotFoundException вы описываете результаты приложения (или зависимости), пытающегося использовать класс, недоступный в версии конфликтной зависимости, которая фактически используется. Существует несколько способов решить эту проблему.

  1. обновите версии библиотек, которые вы используете, которые зависят от конфликтной зависимости, чтобы они все зависит от одной и той же версии версии этой зависимости
  2. объявите конфликтную зависимость как прямую зависимость вашего проекта от версии, которую вы хотите включить (в Примере с отсутствующим классом, включенным в него)
  3. укажите, какую версию конфликтной зависимости должны использовать транзитивные зависимости, через ПМ
  4. явно исключить нежелательные версии конфликтной зависимости из бытия входит в зависимости, которые полагаются на них с помощью <exclusion>

это принципиально не проблема maven, а проблема java. Если проект B и Проект C нуждаются в двух несовместимых версиях проекта D, то вы не можете использовать их оба в проекте A.

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

используя mvn dependency:analyze и mvn dependency:tree помогает в поиске, какие конфликты у вас есть.

вы можете исполнение последовательные зависимости во всем проекте с правилом Сходимость Зависимостей.

 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-enforcer-plugin</artifactId>
     <version>1.3.1</version>
     <executions>
        <execution>
           <id>enforce</id>
           <configuration>
              <rules>
                 <DependencyConvergence/>
              </rules>
           </configuration>
           <goals>
              <goal>enforce</goal>
           </goals>
        </execution>
     </executions>
  </plugin>

одна из возможных стратегий-указать для основного проекта, какую версию D использовать (самую новую f.g.). Однако, если библиотека D не является обратно совместимой, у вас есть проблема, как указано kukudas - невозможно использовать обе библиотеки в вашем проекте.

в такой ситуации может потребоваться использовать либо B, либо C в более старой версии, так что оба будут зависеть от совместимых версий D.

Comments

    Ничего не найдено.