Порядок зависимости 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>