Порядок зависимости Maven

В моем проекте есть класс, реализующий интерфейс. Интерфейс исходит из зависимости. У меня есть другая зависимость, которая сама имеет зависимость от jar, которая также содержит тот же интерфейс, за исключением версии с большим количеством методов; две банки, содержащие один и тот же пакетный интерфейс, НЕ имеют один и тот же идентификатор groupId или artifactId.
Компиляция не работает, потому что компилятор жалуется, что класс в моем проекте не реализует все методы. Я понял, что это потому, что компилятор берет ссылку на интерфейс от неправильной банки. Мой вопрос: почему maven использует интерфейс от транзитивной зависимости, а не от jar, который я явно упоминаю в проекте POM? Я вижу, что используемая банку появляется раньше в определении (так что я тоже представляю себе путь к классу), но я думал, что в этих случаях maven разрешил ее, используя встречный класс/интерфейс из зависимости с кратчайшим путем

Вот часть дерева зависимостей. Обратите внимание, что это grepped, но все же можно заметить, что javax.servlet:servlet-api (фактически используемый) глубже в дереве по сравнению с tomcat:servlet (тот, который должен использоваться)

[[email protected] proj]$ mvn dependency:tree | grep servlet
[INFO] |  +- javax.servlet:servlet-api:jar:2.4:compile
[INFO] +- tomcat:servlet:jar:4.0.6:compile

Я использую maven 3.0.4

Ответы

Ответ 1

почему maven использует интерфейс из транзитивной зависимости а не тот, который из ящика, который я прямо упоминаю в проект POM?

Потому что, к Maven, они не имеют никакого отношения друг к другу. Maven не знает о именах классов или пакетов, Maven просто знает о groupId и artifactId. Так как это не одно и то же, у maven нет причин пропустить транзитивную зависимость.

И если я прав, Maven размещает зависимости от пути к классам в том порядке, в котором они определены, т.е. транзитивные зависимости зависимости a отображаются перед зависимостью b.

Ответ 2

Когда вы объявляете свою зависимость от другого файла jar, вы можете сказать ему, чтобы исключить транзитивную зависимость от конфликтующего файла jar:

    <dependency>
        <groupId>group</groupId>
        <artifactId>artifact</artifactId>
        <version>1.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>othergroup</groupId>
                <artifactId>ArtifactToExclude</artifactId>
            </exclusion>
        </exclusions>
    </dependency>