- Configuring Apache Maven
- MAVEN_OPTS environment variable:
- MAVEN_ARGS environment variable:
- settings.xml file:
- .mvn directory:
- .mvn/extensions.xml file:
- .mvn/maven.config file:
- .mvn/jvm.config file:
- Other guides
- Maven, где мои артефакты? Еще одна статья про управление зависимостями
- Начнем с простого
- Зеркало
- Порядок поиска
- Merge конфигураций
- Поиск пропавших
Configuring Apache Maven
The configuration for Apache Maven usage itself and projects built with resides in a number of places:
MAVEN_OPTS environment variable:
This variable contains parameters used to start up the JVM running Maven and can be used to supply additional options to it. E.g. JVM memory settings could be defined with the value -Xms256m -Xmx512m .
MAVEN_ARGS environment variable:
Starting with Maven 3.9.0, this variable contains arguments passed to Maven before CLI arguments. E.g., options and goals could be defined with the value -B -V checkstyle:checkstyle .
settings.xml file:
Located in USER_HOME/.m2 the settings files is designed to contain any configuration for Maven usage across projects.
.mvn directory:
Located within the project’s top level directory, the files maven.config , jvm.config , and extensions.xml contain project specific configuration for running Maven.
This directory is part of the project and may be checked in into your version control.
.mvn/extensions.xml file:
The old way (up to Maven 3.2.5) was to create a jar (must be shaded if you have other dependencies) which contains the extension and put it manually into the $/lib/ext directory. This means you had to change the Maven installation. The consequence was that everyone who likes to use this needed to change it’s installation and makes the on-boarding for a developer much more inconvenient. The other option was to give the path to the jar on command line via mvn -Dmaven.ext.class.path=extension.jar . This has the drawback giving those options to your Maven build every time you are calling Maven. Not very convenient as well.
From now on this can be done much more simpler and in a more Maven like way. So you can define an $/.mvn/extensions.xml file which looks like the following:
Now you can simply use an extension by defining the usual maven coordinates groupId, artifactId, version as any other artifact. Furthermore all transitive dependencies of those extensions will automatically being downloaded from your repository. So no need to create a shaded artifact anymore.
.mvn/maven.config file:
It’s really hard to define a general set of options for calling the maven command line. Starting with Maven 3.3.1+, this can be solved by putting this options to a script but this can now simple being done by defining $/.mvn/maven.config file which contains the configuration options for the mvn command line.
For example things like -T3 -U —fail-at-end . So you only have to call Maven just by using mvn clean package instead of mvn -T3 -U —fail-at-end clean package and not to miss the -T3 -U —fail-at-end options on every call. The $/.mvn/maven.config is located in the $/.mvn/ directory; also works if in the root of a multi module build.
NOTICE starting with Maven 3.9.0 each single argument must be put in new line, so for the mentioned example your file will have content like:
.mvn/jvm.config file:
Starting with Maven 3.3.1+ you can define JVM configuration via $/.mvn/jvm.config file which means you can define the options for your build on a per project base. This file will become part of your project and will be checked in along with your project. So no need anymore for MAVEN_OPTS , .mavenrc files. So for example if you put the following JVM options into the $/.mvn/jvm.config file
-Xmx2048m -Xms1024m -XX:MaxPermSize=512m -Djava.awt.headless=true
You don’t need to use these options in MAVEN_OPTS or switch between different configurations.
Other guides
The following guides contain further information to specific configuration aspects:
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 сначала проверит наличие артефакта в локальном репозитории в директории $/.m2/repository/ .
Если в локальном репозитории артефакта нет, то запрос пойдет в репозиторий central.
Мы не указывали этот репозиторий, но он всегда добавляется мавеном при сборке.
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 «склеивает» конфиги:
- глобальный — $/conf/settings.xml
- пользовательский — $/.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.
По факту, если при склеивании не возникло конфликтов, то приоритет репозиториев следующий, в порядке уменьшения:
- 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)