Вопрос или проблема
Я хочу быстро увидеть список соответствующих зависимостей модуля. Используя dependency:tree, я хочу отфильтровать внутренние и необязательные зависимости и их соответственно транзитивные зависимости.
Для этого я использую следующую команду
mvn dependency:tree -Dscope=runtime \
-Dexcludes={dependencies}
Тем не менее, некоторые из зависимостей, которые я исключаю, все еще находятся в выходном дереве, и мне бы хотелось знать, делаю ли я что-то не так
Пример с использованием spring-ws версии 4.0.11, подсистема spring-ws-core
Без исключений я вижу зависимости для jakarta.mail-api
и jaxb-runtime
:
mvn -o dependency:tree -Dscope=runtime \
| grep -E '(jakarta.mail-api|jaxb-runtime)'
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.5:runtime
[INFO] +- jakarta.mail:jakarta.mail-api:jar:2.1.3:compile
Исключение jakarta.mail-api
с помощью только groupId:artifactId, похоже, срабатывает
mvn -o dependency:tree -Dscope=runtime \
-Dexcludes=jakarta.mail:jakarta.mail-api \
| grep -E '(jakarta.mail-api|jaxb-runtime)'
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.5:runtime
Однако я не могу сказать того же про jaxb-runtime
mvn -o dependency:tree -Dscope=runtime \
-Dexcludes=org.glassfish.jaxb:jaxb-runtime \
| grep -E '(jakarta.mail-api|jaxb-runtime)'
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.5:runtime
[INFO] +- jakarta.mail:jakarta.mail-api:jar:2.1.3:compile
Фильтрация, похоже, работает только на конкретных зависимостях, исключая только фильтры jakarta.mail-api, что также работало, если зак excluded только индивидуально
mvn -o dependency:tree -Dscope=runtime \
-Dexcludes=jakarta.mail:jakarta.mail-api,org.glassfish.jaxb:jaxb-runtime \
| grep -E '(jakarta.mail-api|jaxb-runtime)'
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.5:runtime
Есть несколько зависимостей, которые, похоже, работают, и другие, которые совсем не работают. Я не вижу здесь паттерна. Я мог бы просто отфильтровать их с помощью grep -v
, но это оставит мне транзитивные зависимости.
Ответ или решение
Вопрос, который вы подняли, связан с использованием Maven Dependency Plugin и его параметра -Dexcludes
. Давайте глубже рассмотрим, почему выполнение команды dependency:tree -Dexcludes=a.b.c
не всегда приводит к корректному исключению зависимости a.b.c
из дерева зависимостей.
Почему не происходит исключение зависимости
-
Область зависимости:
Одной из первопричин, по которой зависимости могут не исключаться, является область, в которой они определены. Maven имеет разные области зависимостей, такие какcompile
,runtime
,test
и т.д. Командаmvn dependency:tree -Dscope=runtime
будет показывать только зависимости, относящиеся к времени выполнения, и если указанная вами зависимостьa.b.c
находится в другой области (например,compile
), то она не будет исключена. В вашем случае возможно, чтоjaxb-runtime
или другие зависимости, которые не исключаются, были определены в области, отличной отruntime
. -
Транзитивные зависимости:
В Maven зависимости могут иметь транзитивные зависимости, которые также могут влиять на поведение вашего запроса. Например, еслиjaxb-runtime
является транзитивной зависимостью для некоторой зависимости, которая не включает ограничение-Dexcludes
, то эта зависимость продолжит появляться в результатах, несмотря на вашу попытку исключить её. Это означает, что исключение может не повлиять на все места, откуда зависит ваша основная зависимость. -
Степень вложенности:
Когда вы исключаете зависимость, это не всегда означает, что все её транзитивные зависимости также будут исключены. Если зависимость, такую какjaxb-runtime
, используется в нескольких местах с разными версиями или областями, ваше исключение может оказать влияние только на конкретный путь. -
Неправильный синтаксис исключений:
При использовании-Dexcludes
важно следить за правильностью указания группы и артефакта. Например, если вы используетеorg.glassfish.jaxb:jaxb-runtime
, убедитесь, что это точное имя и версия зависимости, которые вы хотите исключить. Пробелы, переносы строк и другие синтаксические ошибки могут привести к неожиданным результатам.
Примеры и возможные решения
В вашем примере, когда вы пытались исключить jaxb-runtime
, команда не сработала. Это может быть связано с тем, что эта зависимость могла быть добавлена как транзитивная со стороны другой зависимости, которая имеет более высокий приоритет.
Рекомендации:
- Проверьте, какие зависимости вы пытаетесь исключить, и убедитесь, что они действительно заданы в области, которую вы собираетесь фильтровать.
- Попробуйте выполнить команду
mvn dependency:tree -Dverbose
, чтобы увидеть, как и откуда появляются зависимости. Это поможет вам понять, почему некоторые из них не исключаются. - Рассмотрите возможность нескольких запусков команды с различными вариантами
-Dexcludes
, чтобы удостовериться, что вы исключаете все нежелательные зависимости на всех уровнях дерева зависимостей.
Заключение
Система управления зависимостями Maven достаточно мощная, но она также имеет свои особенности, которые могут вызывать путаницу, если не учитывать архитектуру зависимостей и структуру проекта. Использование точных команд и понимание того, как работает транзитивность, могут значительно облегчить вам работу с зависимостями. Экспериментируйте с комбинированием исключений, а также используйте расширенные команды для диагностики, чтобы в конечном итоге добиться желаемого результата.