Подтвердить что ты не робот

Почему порядок зависимости от Maven имеет значение?

Я думал, что порядок зависимостей Maven не имеет значения до этого и рассматривает это как профессионал. И это мои старые pom.xml зависимости:

<dependencies>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.19</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.1.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-spring3</artifactId>
        <version>2.19</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-moxy</artifactId>
        <version>2.19</version>
    </dependency>

</dependencies>

Это хорошо работает, и сегодня я хочу переместить зависимость spring на дно, чтобы эти трикотажные изделия могли быть вместе. Однако я больше не могу заставить его работать, мой Jetty жалуется:

[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run (default-cli) on project mtest: Execution default-cli of goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run failed: A required class was missing while executing org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run: org/apache/commons/logging/LogFactory

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

4b9b3361

Ответ 1

Порядок зависимостей имеет значение из-за того, как Maven разрешает переходные зависимости, начиная с версии 2.0.9. Выдержка из документации:

(...) определяет, какая версия зависимости будет использоваться, когда встречаются несколько версий артефакта. (...) Вы всегда можете гарантировать версию, объявив ее явно в своем проекте POM. (...), так как Maven 2.0.9 это порядок в объявлении, который считает: первое объявление выигрывает.

Ответ 2

Чтобы развернуть другой ответ (в котором говорится, что порядок объявления влияет на посредничество зависимостей Maven для транзитивных зависимостей), есть несколько инструментов, которые вы можете использовать:

  • mvn dependency:tree [-Dscope=[runtime|test]] покажет вам, какие зависимости будут доступны для выбранной области. Подробнее см. здесь
  • mvn dependency:build-classpath дает вам порядок, в котором зависимости доступны в вашем пути к классам (если две или более записи в classpath имеют один и тот же класс, предыдущий выигрывает). Подробнее см. здесь

Я не знаю много о вашей ситуации, но часто бывает, что вы завершаете неправильную версию 1 или более банок при компиляции/времени выполнения. Объявление вашей собственной версии библиотеки или блокировка версии с помощью <dependencyManagement> здесь являются параметрами.

Теперь, чтобы ответить на ваш другой вопрос - как вы знаете, что такое правильный порядок при объявлении зависимостей?

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

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