Решение проблем конвергенции зависимостей Maven
Я использую Maven-enforcer-plugin для проверки проблем конвергенции зависимостей. Типичным выходом будет:
[WARNING] Rule 1: org.apache.maven.plugins.enforcer.DependencyConvergence failed
with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for junit:junit:3.8.1 paths to dependency are:
+-foo:bar:1.0-SNAPSHOT
+-ca.juliusdavies:not-yet-commons-ssl:0.3.9
+-commons-httpclient:commons-httpclient:3.0
+-junit:junit:3.8.1
and
+-foo:bar:1.0-SNAPSHOT
+-junit:junit:4.11
]
видя это сообщение, я обычно "решаю" его, исключая транзитивную зависимость, например
<dependency>
<groupId>ca.juliusdavies</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.9</version>
<exclusions>
<!-- This artifact links to another artifact which stupidly includes
junit in compile scope -->
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
Я хотел бы понять, действительно ли это исправление и риски, связанные с исключением библиотек таким образом. Как я это вижу:
"исправление" обычно безопасно, при условии, что я выбираю использовать более новую версия. Это зависит от авторов библиотеки, поддерживающих обратную совместимость.
обычно нет никакого влияния на сборку Maven (так как более близкое определение выигрывает), однако, исключая зависимость, я говорю Maven, что я знаю об этой проблеме и, таким образом, успокаивая Maven-enforcer-plugin.
верны ли мои мысли и есть ли альтернативный способ решения этой проблемы? Меня интересуют ответы, которые сосредоточены на общем случай-я понимаю junit
пример выше немного странный.
2 ответов
мы все согласны с тем, что JUnit никогда не должен быть установлен в другую область, чем test
. Вообще говоря, я не думаю, что есть другое решение, чем исключение нежелательной зависимости, поэтому мы все согласны с тем, что вы правы.
ПРОСТОЙ СЛУЧАЙ:
как говорит Андреас Крюгер, может быть риск с версиями (я действительно столкнулся с этим). Предположим, что зависимости проекта следующие:
+-foo:bar:1.0-SNAPSHOT
+-group1:projectA:2.0
+-group2:projectB:3.8.1
+-group2:projectB:4.11
обратите внимание, что это просто упрощение вашего дела. Увидев это дерево зависимостей, вы исключите зависимость projectB, заданную projectA:
<dependency>
<groupId>group1</groupId>
<artifactId>projectA</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>group2</groupId>
<artifactId>projectB</artifactId>
</exclusion>
</exclusions>
</dependency>
после упаковки проекта с maven оставшаяся зависимость будет group2-someProjectB-4.11.jar, версия 4.11, а не 3.8.1. Все будет хорошо, и проект будет работать без каких-либо проблем.
затем, через некоторое время, скажем, что вы решили перейти на следующую версию проекта A, версия 3.0, которая добавляет новые возможности :
<dependency>
<groupId>group1</groupId>
<artifactId>projectA</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<groupId>group2</groupId>
<artifactId>projectB</artifactId>
</exclusion>
</exclusions>
</dependency>
проблема в том, что вы еще не в курсе что projectA версии 3.0 также обновили свою зависимость projectB до версии 5.0:
+-foo:bar:1.0-SNAPSHOT
+-group1:projectA:3.0
+-group2:projectB:5.0
+-group2:projectB:4.11
в этом случае исключение, которое вы сделали бы некоторое время назад, исключает projectB версии 5.0.
однако, projectA версии 3.0 нуждается в улучшениях от project B версии 5.0. Из-за исключения, после упаковки проекта с maven, оставшаяся зависимость будет group2-someProjectB-4.11.jar, версия 4.11, а не 5.0. На данный момент Вы используете любую из новых функций projectA, программа не будет работать правильно.
КАКОВО БЫЛО РЕШЕНИЕ ?
я столкнулся с этой проблемой в проекте Java-EE.
команда разработала службы баз данных. Они упаковали его как projectA. Каждый раз, когда они обновляли службы, они также обновляли файл со списком всех своих текущих зависимостей и текущая версия.
ProjectA была зависимостью для проекта Java-EE, над которым я работал. Каждый раз, когда команда службы обновляла ProjectA, я также проверял обновления версий.
на самом деле, нет никакого вреда в исключении зависимости. но каждый раз, когда вы обновляете зависимость, в которой установлено исключение, вы должны проверить:
- если это исключение все-таки есть смысл.
- если вам нужно обновить версию исключена зависимость в вашем собственном проекте.
Я думаю, исключения maven похожи на кухонные ножи. Он острый, режет овощи без усилий, но требует осторожности при обращении с ним...
Если JUnit как артефакт проходит как зависимость в области компиляции, это ошибка одной из ваших библиотек, здесь: ca.juliusdavies.
JUnit всегда должен быть включен в область тестирования. Таким образом, это не упакованный в произведенное .сосуд. ,война или. файл ear, при успешной сборке.
вообще говоря, нет никакого вреда в исключении уже включенных зависимостей, например, когда библиотека 1 и библиотека 2 имеют одну общую зависимость.
только проблема, конечно, может возникнуть, когда библиотека 1 и библиотека 2 включают разные версии одного и того же зависимого артефакта. Это может вызвать ошибки во время выполнения, когда функции библиотеки изменились. К счастью, это не так часто бывает, если разница в номерах версий не велика. В общем, рекомендуется включить последнюю версию зависимостей и исключить более старую. Это в большинстве случаев жизнеспособно.
Если нет, проверьте, есть ли обновления зависимостей первого уровня вашего проекта.