[Из песочницы] Maven, где мои артефакты? Еще одна статья про управление зависимостями
Легко жить с maven, когда есть доступ к центральному репозиторию, или у компании есть один корпоративный репозиторий. Все меняется, если работаешь в закрытом контуре, а количество репозиториев ближе к сотне. Под катом история о том, где искать потерявшийся артефакт и как для этого приготовить maven.
Что будет?
В статье будут примеры настройки settings, pom, описание поиска в репозиториях. Не будет настройки nexus\artifactory, проблем связанных с ними.
Начнем с простого
Добавим зависимость на spring в своем pom.
org.springframework
spring-webmvc
5.0.0.RELEASE
4.0.0
test
dependency-testing
1.0.0
Dependency test
org.springframework
spring-webmvc
5.0.0.RELEASE
Предположим, что мы только установили maven и не меняли никаких настроек. После инициализации поиска зависимостей через сборку maven, или через ide, maven сначала проверит наличие артефакта в локальном репозитории в директории ${user.home}/.m2/repository/
.
Если в локальном репозитории артефакта нет, то запрос пойдет в репозиторий central.
Мы не указывали этот репозиторий, но он всегда добавляется мавеном при сборке.
Сконфигурируем settings.xml
nexus-corp
nexus-corp-repo
http://nexus.mycompany.com:8081/nexus/central/
nexus
nexus
Подробнее про settings.xml
С такой конфигурацией порядок поиска будет аналогичен варианту с конфигурацией по умолчанию, но появится дополнительный шаг. Перед тем как пойти в central, мавен попытается скачать артефакт из репозитория nexus-corp.
Зеркало
Добавим зеркало для репозитория nexus-corp.
nexus-corp-mirror
nexus-corp-mirror
http://nexus.mirror.mycompany.com:8081/nexus/central/
nexus-corp
- недоступен внешний репозиторий
- для экономии внешнего трафика
- чтобы переопределить репозиторий из settings\pom
Подробнее про зеркала
Когда maven дойдет до шага поиска в репозитории nexus-corp, то вместо него попытается найти артефакт в репозитории nexus-corp-mirror.
При этом если он не найдет его в nexus-corp-mirror, то запроса в nexus-corp не будет.
А если добавить зеркало с wildcard, то все запросы будут направлены на него, если не указаны другие зеркала.
all
nexus-corp-mirror
http://nexus.mirror.mycompany.com:8081/nexus/central/
*
Порядок поиска
В общем случае схема поиска будет такой:
1. Поиск в локальном репо
2. Поиск в репозиториях в порядке объявления с учетом приоритета (либо в их зеркалах)
В конце добавляется central. Он всегда последний, если не был перезаписан.
Merge конфигураций
Перед выполнением сборки maven «склеивает» конфиги:
- глобальный —
${maven.home}/conf/settings.xml
- пользовательский —
${user.home}/.m2/settings.xml
- проектный —
pom.xml
С приоритетом конфигурацией у меня случился небольшой конфуз. В документации написано:
The former settings.xml are also called global settings, the latter settings.xml are referred to as user settings. If both files exists, their contents gets merged, with the user-specific settings.xml being dominant.
По факту, если при склеивании не возникло конфликтов, то приоритет репозиториев следующий, в порядке уменьшения:
- глобальный
- пользовательский
- pom.xml
Из примеров ниже порядок будет следующий:
- repo-global-setting1
- repo-user-setting1
- repo-user-setting2
- repo-pom1
- central
repo-global-setting1
http://nexus.mycompany.com:8081/nexus/repo-global-setting1-url/
g-nexus
g-nexus
repo-user-setting1
http://nexus.mycompany.com:8081/nexus/repo-user-setting1-url/
repo-user-setting2
http://nexus.mycompany.com:8081/nexus/repo-user-setting2-url/
nexus
nexus
4.0.0
test
dependency-testing
1.0.0
Dependency test
repo-pom1
http://nexus.mycompany.com:8081/nexus/repo-pom1-url/
org.slf4j
slf4j-api
1.7.25
С разрешением конфликтов появилось еще большее непонимание. Если объявить репозиторий с одним id в разных профилях, то приоритет имеет глобальный конфиг, но если объявить профили с одинаковым id, то приоритет имеет пользовательский. Дальше экспериментировать уже не стал.
Поиск пропавших
Так что делать с ошибкой Could not resolve dependencies for project myproject:jar:1.0.0: Failed to collect dependencies at com.someproject:artifact-name:jar:1.0.0
?
1. Проверить правильность имени и версии артефакта.
2. Посмотреть какие репозитории\зеркала указаны в ваших settings\pom.
3. Проверить наличие артефакта в этих репозиторииях
Обычно проблема решается на втором шаге, но кроме этих пунктов встречаются проблемы из-за прокси, также бывает, что скаченный jar поврежден (хотя сам я сталкивался с таким всего один раз).
Для snapshot версий полезна команда -U — принудительное обновление snapshot зависимостей. По умолчанию maven обновляет их только после истечения таймаута раз в день (параметр updatePolicy)
В ролях
maven 3.5.0
jdk 1.8
debug логи maven