Java for Beginner
695 subscribers
603 photos
165 videos
12 files
932 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Плагины и цели Maven

Плагины и цели (goals) являются ключевыми компонентами Maven, обеспечивающими выполнение конкретных задач в процессе сборки. Они интегрируются с жизненным циклом Maven, позволяя разработчикам компилировать код, запускать тесты, создавать артефакты и выполнять другие действия.


Что такое плагин и цель


Плагин в Maven — это модуль, содержащий набор функций для выполнения задач сборки, таких как компиляция, тестирование или развертывание. Каждый плагин состоит из одной или нескольких целей (goals), которые представляют собой конкретные действия, выполняемые плагином. Например, плагин maven-compiler-plugin имеет цели compile (компиляция исходного кода) и testCompile (компиляция тестового кода).

Цели привязываются к фазам жизненного цикла Maven (например, compile, test, package), что позволяет автоматически вызывать их в нужный момент сборки. Плагины и их цели загружаются в память как Java-объекты во время выполнения, что делает их гибкими, но требует внимания к управлению ресурсами.


Архитектура Maven Plugins

Плагины Maven построены на основе архитектуры, которая использует Plexus — контейнер инверсии управления (IoC), встроенный в Maven. Каждый плагин представляет собой JAR-файл, содержащий Java-классы, реализующие интерфейс org.apache.maven.plugin.Mojo.

Основные аспекты архитектуры:
Mojo (Maven plain Old Java Object): Основной строительный блок плагина. Mojo — это Java-класс, реализующий интерфейс Mojo, который определяет метод execute() для выполнения задачи. Каждый Mojo соответствует одной цели плагина. Например, в maven-compiler-plugin цель compile реализована классом CompilerMojo.
Plexus Container: Управляет жизненным циклом плагинов, загружая их классы и зависимости. Plexus создает изолированные классовые загрузчики (classloaders) для каждого плагина, чтобы избежать конфликтов зависимостей.
POM Model Integration: Плагины получают доступ к объектной модели проекта (POM) через API
Maven, что позволяет им читать конфигурацию, зависимости и свойства проекта.
Descriptor File: Каждый плагин содержит файл META-INF/
maven/plugin.xml, описывающий его цели, параметры и привязки к фазам жизненного цикла.

В памяти плагины загружаются как экземпляры Mojo, каждый из которых хранит свою конфигурацию и состояние. Это увеличивает потребление памяти, особенно при использовании множества плагинов или сложных конфигураций. Maven оптимизирует загрузку, кэшируя зависимости плагинов в локальном репозитории (~/.m2/repository), но интенсивные задачи, такие как компиляция, могут временно увеличивать использование оперативной памяти.

#Java #middle #Maven #Plugin #Goals
👍1
Встроенные плагины

Maven поставляется с набором встроенных плагинов, которые покрывают основные задачи сборки. Они определены в "super POM" — базовом POM-файле, который наследуется всеми проектами.

Рассмотрим ключевые встроенные плагины:

maven-compiler-plugin: Отвечает за компиляцию исходного и тестового кода. Цели:
compile: Компилирует исходный код в target/classes.
testCompile: Компилирует тестовый код в target/test-classes. В памяти плагин загружает исходные файлы, зависимости и настройки компилятора, создавая временные структуры данных для байт-кода.
maven-surefire-plugin: Выполняет модульные тесты. Основная цель:
test: Запускает тесты с использованием фреймворков, таких как JUnit или TestNG, и сохраняет результаты в target/surefire-reports. Плагин создает изолированную среду выполнения тестов, что требует дополнительной памяти для загрузки тестовых классов и их зависимостей.
maven-jar-plugin: Создает JAR-артефакты. Основная цель:
jar: Пакует скомпилированный код и ресурсы в JAR-файл в target. Плагин работает с файловой системой, минимизируя использование памяти, так как данные записываются непосредственно на диск.
maven-install-plugin: Устанавливает артефакты в локальный репозиторий. Цель:
install: Копирует артефакт в ~/.m2/repository. Плагин использует минимальный объем памяти, так как выполняет операции копирования файлов.
maven-deploy-plugin: Разворачивает артефакты в удаленный репозиторий. Цель:
deploy: Загружает артефакт в указанный репозиторий (например, Nexus или Artifactory). Плагин взаимодействует с сетью, что может замедлить выполнение, но не сильно нагружает память.
maven-site-plugin: Генерирует документацию проекта. Цели:
site: Создает HTML-документацию в target/site.
site-deploy: Разворачивает документацию на сервер. Плагин загружает в память шаблоны и данные проекта, что может быть ресурсоемким для крупных проектов.


Эти плагины автоматически привязаны к соответствующим фазам жизненного цикла (например, maven-compiler-plugin:compile к фазе compile), что определено в super POM. Их поведение можно переопределить или расширить в пользовательском POM-файле.


Конфигурация плагинов: <plugin>, <executions>, <configuration>


Конфигурация плагинов задается в POM-файле через элемент <plugin>.

Основные элементы конфигурации:
<plugin>: Определяет плагин, его groupId, artifactId и version.

Например:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>


<configuration>: Задает параметры плагина, такие как версия Java или дополнительные опции.

Например:
```
<configuration>
<source>11</source>
<target>11</target>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
</configuration>

Параметры загружаются в память как свойства объекта Mojo, что позволяет плагину адаптировать поведение.
```

<executions>: Позволяет привязать цели плагина к конкретным фазам жизненного цикла или настроить многократное выполнение цели.

Например:
<executions>
<execution>
<id>custom-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</execution>
</executions>

Каждая <execution> создает отдельный экземпляр Mojo в памяти, что может увеличить потребление ресурсов при сложных конфигурациях.


Конфигурация загружается в объектную модель POM во время инициализации проекта. Maven парсит XML, создавая структуры данных, которые хранятся в оперативной памяти. Для крупных проектов с множеством плагинов это может привести к значительному потреблению памяти, особенно если конфигурации содержат сложные параметры или большие списки зависимостей.

#Java #middle #Maven #Plugin #Goals
👍1
Наследование и управление версиями плагинов

Maven поддерживает наследование конфигураций плагинов через родительские POM-файлы.

В многомодульных проектах родительский POM может определять общие плагины и их версии в секции <pluginManagement>:

<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>


Дочерние модули наследуют эти настройки, но могут их переопределить. Это позволяет централизованно управлять версиями плагинов, минимизируя дублирование кода. В памяти Maven хранит только одну копию конфигурации из <pluginManagement>, которая копируется в дочерние модели POM при необходимости, оптимизируя использование ресурсов.

Управление версиями также осуществляется через локальный и удаленные репозитории. Maven загружает плагины из ~/.m2/repository или скачивает их из центрального репозитория (например, Maven Central). Кэширование плагинов снижает нагрузку на сеть, но требует места на диске.


Mojo (Maven plain Old Java Object)

Mojo — это Java-класс, реализующий интерфейс org.apache.maven.plugin.Mojo. Он определяет логику выполнения цели плагина.

Основные элементы Mojo:
Аннотации: Используются для указания имени цели, привязки к фазе и параметров.

Например:
```
@Mojo(name = "custom-goal", defaultPhase = LifecyclePhase.COMPILE)
public class CustomMojo extends AbstractMojo {
@Parameter(property = "customParam", defaultValue = "value")
private String customParam;

public void execute() throws MojoExecutionException {
getLog().info("Executing custom goal with param: " + customParam);
}
}

Аннотация @Parameter позволяет связать поле класса с параметром из POM-файла.
```

Метод execute(): Содержит логику выполнения цели. Может взаимодействовать с моделью POM, файловой системой и другими ресурсами.
Логирование: Используется метод getLog() для вывода сообщений в консоль
Maven.

В памяти каждый Mojo создается как отдельный объект, связанный с конкретной целью и фазой. Plexus управляет жизненным циклом Mojo, создавая и уничтожая их по мере выполнения фаз. Это может привести к фрагментации памяти, если плагин выполняет ресурсоемкие операции, такие как обработка больших файлов.


Сторонние плагины

Сторонние плагины расширяют функциональность Maven, добавляя поддержку задач, не покрытых встроенными плагинами.

Примеры популярных сторонних плагинов:
findbugs-maven-plugin: Выполняет статический анализ кода для поиска ошибок.
maven-shade-plugin: Создает "uber-JAR", включая зависимости.
docker-
maven-plugin: Интегрирует сборку Docker-образов в процесс Maven.

Сторонние плагины добавляются в POM-файл аналогично встроенным:
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.3.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>


Сторонние плагины загружаются из репозиториев, указанных в POM-файле, и могут увеличивать потребление памяти, особенно если они используют дополнительные библиотеки. Например, maven-shade-plugin загружает в память все зависимости артефакта для создания uber-JAR, что может быть ресурсоемким для крупных проектов.


#Java #middle #Maven #Plugin #Goals
Создание собственного плагина

Создание собственного плагина позволяет реализовать специфические задачи сборки.

Процесс включает следующие шаги:
Создание проекта Maven: Используйте архетип maven-archetype-mojo для генерации структуры:
mvn archetype:generate -DgroupId=com.example -DartifactId=custom-maven-plugin -DarchetypeArtifactId=maven-archetype-mojo

Реализация Mojo: Создайте Java-класс, реализующий AbstractMojo.

Например:
package com.example;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

@Mojo(name = "say-hello")
public class HelloMojo extends AbstractMojo {
@Parameter(property = "message", defaultValue = "Hello, Maven!")
private String message;

public void execute() throws MojoExecutionException {
getLog().info(message);
}
}


Конфигурация plugin.xml: Файл META-INF/maven/plugin.xml генерируется автоматически и содержит метаданные о целях и параметрах.

Сборка и установка:
mvn clean install


Использование плагина: Добавьте плагин в POM-файл другого проекта:
<plugin>
<groupId>com.example</groupId>
<artifactId>custom-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>say-hello</goal>
</goals>
</execution>
</executions>
</plugin>


Создание плагина требует загрузки дополнительных зависимостей, таких как maven-plugin-api и maven-plugin-annotations, в память. Плагин компилируется как обычный Java-проект, а его цели становятся доступны для привязки к фазам жизненного цикла. Важно оптимизировать логику Mojo, чтобы минимизировать потребление памяти, особенно если плагин обрабатывает большие объемы данных.


Нюансы и внутренние механизмы

Управление памятью:
Плагины загружаются как отдельные JAR-файлы, каждый со своим классовым загрузчиком. Это изолирует зависимости, но увеличивает фрагментацию памяти.
Mojo-объекты создаются для каждой цели в рамках <execution>. Многократное выполнение цели увеличивает потребление памяти.
Для оптимизации используйте флаги JVM, такие как -Xmx, и минимизируйте количество одновременно выполняемых плагинов.


Конфликты зависимостей:
Разные плагины могут использовать разные версии одной и той же библиотеки. Maven решает это с помощью изолированных загрузчиков классов, но это может привести к увеличению памяти или ошибкам, если плагин неправильно настроен.

Кэширование:
Maven кэширует плагины и их зависимости в ~/.m2/repository, что снижает нагрузку на сеть. Однако при использовании устаревших версий плагинов могут возникнуть проблемы совместимости.

Параллельное выполнение:
В многомодульных проектах плагины могут выполняться параллельно с флагом -T. Это ускоряет сборку, но увеличивает пиковое потребление памяти из-за одновременной загрузки нескольких Mojo.

Отладка:
Для отладки плагинов используйте флаг -X или настройте логирование в Mojo через getLog(). Это помогает выявить проблемы, но увеличивает объем выводимых данных.


#Java #middle #Maven #Plugin #Goals
👍1
Управление зависимостями в Maven

Управление зависимостями — одна из ключевых возможностей Maven, которая позволяет автоматизировать загрузку, разрешение и использование библиотек в проекте. Maven обеспечивает централизованное управление зависимостями через локальный и удаленные репозитории, а также предоставляет механизмы для работы с транзитивными зависимостями, разрешения конфликтов и настройки специфичных сценариев.


Механизм разрешения зависимостей


Maven использует декларативный подход к управлению зависимостями, которые определяются в файле POM.xml в секции <dependencies>.

Каждая зависимость указывается через три ключевых атрибута:
groupId: Уникальный идентификатор организации или проекта.
artifactId: Имя артефакта.
version: Версия артефакта.


Пример:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>


Когда Maven выполняет сборку, он разрешает зависимости следующим образом:
Загрузка POM-модели: Maven парсит POM.xml, создавая объектную модель проекта (POM model) в оперативной памяти. Эта модель включает информацию о зависимостях, репозиториях и настройках.
Поиск зависимостей:
Maven сначала проверяет локальный репозиторий (~/.m2/repository). Если зависимость отсутствует, он обращается к удаленным репозиториям, указанным в <repositories> или унаследованным из super POM (по умолчанию Maven Central).
Загрузка артефактов:
Maven скачивает JAR-файлы и их POM-файлы, сохраняя их в локальном репозитории. В памяти создаются структуры данных, представляющие зависимости, включая их метаданные (groupId, artifactId, version).
Разрешение транзитивных зависимостей:
Maven анализирует POM-файлы загруженных зависимостей, чтобы определить их собственные зависимости (см. ниже).

В памяти Maven хранит граф зависимостей — направленный ациклический граф (DAG), где узлы представляют зависимости, а ребра — их взаимосвязи. Этот граф используется для определения порядка загрузки и разрешения конфликтов. Размер графа зависит от количества зависимостей и их транзитивных связей, что может значительно увеличивать потребление памяти в крупных проектах.


Транзитивные зависимости

Транзитивные зависимости — это зависимости, которые требуются другим зависимостям. Например, если проект зависит от spring-core, а spring-core требует commons-logging, то commons-logging становится транзитивной зависимостью.


Maven автоматически включает транзитивные зависимости в сборку, что упрощает управление, но может привести к конфликтам или ненужным библиотекам.

Процесс разрешения транзитивных зависимостей:
Maven загружает POM-файл каждой зависимости и рекурсивно анализирует их <dependencies>.
Все найденные зависимости добавляются в граф зависимостей, который хранится в памяти.
Maven применяет правила разрешения конфликтов (см. ниже) для выбора подходящих версий.

Транзитивные зависимости увеличивают объем данных в памяти, так как Maven должен загрузить и обработать все связанные POM-файлы. Для оптимизации Maven кэширует зависимости в локальном репозитории, но при первом разрешении или при использовании флага --update-snapshots может происходить интенсивная сетевая активность.


Dependency Mediation и Nearest-Wins Strategy

Когда разные зависимости требуют одну и ту же библиотеку, но с разными версиями, возникает конфликт.

Maven использует стратегию dependency mediation с правилом nearest-wins (ближайший побеждает):
Nearest-wins strategy: Maven выбирает версию зависимости, которая находится ближе к корню графа зависимостей (т.е. имеет меньшую глубину в цепочке транзитивных зависимостей).
Пример: Если проект напрямую зависит от commons-logging:1.2, а другая зависимость требует commons-logging:1.1, то
Maven выберет 1.2, так как она указана в корневом POM-файле (глубина 1). Если обе версии находятся на одинаковой глубине, Maven выберет ту, что встретилась первой в порядке парсинга.

#Java #middle #Maven #Dependencies
👍3
В памяти Maven строит граф зависимостей, где каждая версионная коллизия разрешается путем выбора ближайшей версии. Это требует хранения временных структур данных для сравнения версий, что может быть ресурсоемким для проектов с большим количеством зависимостей.

Для явного контроля версий можно использовать секцию <dependencyManagement> в POM-файле:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>


Зависимости, указанные в <dependencyManagement>, имеют приоритет над транзитивными, что позволяет избежать конфликтов. Эти данные загружаются в память как часть POM-модели и применяются во время разрешения графа.


Dependency Convergence

Dependency convergence — это концепция, которая требует, чтобы в графе зависимостей использовалась только одна версия каждой библиотеки. Нарушение конвергенции (например, использование двух версий одной библиотеки) может привести к ошибкам, таким как ClassNotFoundException или несовместимость API.


Для обеспечения конвергенции используется плагин maven-enforcer-plugin с правилом dependencyConvergence:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
</execution>
</executions>
</plugin>


Если плагин обнаруживает конфликт версий, сборка завершается с ошибкой. В памяти maven-enforcer-plugin загружает полный граф зависимостей для анализа, что может значительно увеличить потребление ресурсов в крупных проектах.


Optional Dependencies

Опциональные зависимости (<optional>true</optional>) — это зависимости, которые не включаются в транзитивный граф проектов, использующих данный артефакт. Они полезны, когда библиотека предоставляет дополнительные функции, которые не требуются всем потребителям.


Пример:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<optional>true</optional>
</dependency>


Если проект A включает slf4j-api как опциональную зависимость, то проект B, зависящий от A, не унаследует slf4j-api, пока не объявит его явно. Это уменьшает размер графа зависимостей, снижая потребление памяти и вероятность конфликтов.

В памяти Maven отмечает опциональные зависимости в POM-модели, исключая их из транзитивного разрешения, что оптимизирует обработку графа.


BOM (Bill of Materials)

BOM-файл — это специальный POM-файл, который определяет версии зависимостей для согласованного управления ими в проекте или группе проектов. BOM используется через <dependencyManagement> с областью видимости (scope) import.

Пример использования BOM от Spring Boot:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.18</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


BOM-файл загружается в память как часть POM-модели и предоставляет централизованный список версий, которые применяются ко всем зависимостям в проекте. Это упрощает управление версиями и обеспечивает согласованность, особенно в многомодульных проектах. В памяти BOM увеличивает объем данных, так как Maven должен загрузить и обработать дополнительный POM-файл.

#Java #middle #Maven #Dependencies
👍3
Использование import scope

Область видимости import используется исключительно в <dependencyManagement> для импорта BOM-файлов. Она позволяет включить конфигурацию зависимостей из внешнего POM-файла, не добавляя сам артефакт в сборку.

Пример:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>custom-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


В памяти
Maven загружает импортированный POM-файл как часть модели проекта, добавляя его зависимости в структуру <dependencyManagement>. Это увеличивает потребление памяти, но упрощает управление версиями, так как все модули проекта используют единый набор версий.


Dependency Tree (mvn dependency:tree) и анализ конфликтов

Плагин maven-dependency-plugin с целью tree позволяет визуализировать граф зависимостей:
mvn dependency:tree


Пример вывода:
[INFO] com.example:my-project:jar:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:5.3.20:compile
[INFO] | \- commons-logging:commons-logging:jar:1.2:compile
[INFO] \- org.junit.jupiter:junit-jupiter:jar:5.9.2:test


Команда dependency:tree загружает в память полный граф зависимостей, включая транзитивные зависимости, и выводит его в консоль. Это полезно для анализа конфликтов и выявления нежелательных зависимостей. Для более детального анализа можно использовать флаг -Dverbose для отображения исключенных или конфликтующих версий.


Для разрешения конфликтов можно:
Исключить зависимости:
```
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

Исключения уменьшают размер графа зависимостей, снижая потребление памяти.
Явно указать версию в <dependencyManagement> для принудительного выбора версии.

```

Использовать dependency:analyze для выявления неиспользуемых или необъявленных зависимостей:
mvn dependency:analyze


В памяти dependency:tree создает временные структуры для хранения графа, что может быть ресурсоемким для проектов с сотнями зависимостей. Оптимизация, такая как использование <exclusions> или BOM, помогает сократить объем данных.


Нюансы и внутренние механизмы

Управление памятью:
Граф зависимостей хранится в памяти как DAG, где каждый узел представляет артефакт, а ребра — зависимости. Размер графа пропорционален количеству зависимостей.
Maven использует Aether (библиотеку для работы с репозиториями), которая загружает метаданные зависимостей в память. Это может привести к пиковому потреблению памяти при первом разрешении.
Для оптимизации используйте флаг -o (offline) для работы с локальным кэшем или настройте JVM с помощью -Xmx.


Кэширование:
Локальный репозиторий (~/.m2/repository) кэширует JAR-файлы, POM-файлы и метаданные, что снижает сетевую нагрузку.
Maven хранит метаданные о версиях в файлах _remote.repositories, что ускоряет повторное разрешение.

Конфликты и Classpath:
Неправильное разрешение зависимостей может привести к включению двух версий одной библиотеки в classpath, вызывая ошибки вроде NoClassDefFoundError.
Используйте dependency:tree и
maven-enforcer-plugin для предотвращения таких проблем.

Параллельное разрешение:
В многомодульных проектах Maven разрешает зависимости для каждого модуля отдельно, но кэширует результаты в памяти. Параллельное выполнение (-T) увеличивает пиковое потребление памяти из-за одновременной обработки нескольких графов.

Сетевые проблемы:
Если удаленный репозиторий недоступен, Maven может завершиться с ошибкой. Настройка зеркал в settings.xml или использование --offline помогает избежать этого.


#Java #middle #Maven #Dependencies
👍4
Профили, настройки и переменные в Maven

Maven предоставляет мощные инструменты для адаптивной конфигурации проектов, включая профили, настройки в файле settings.xml и использование переменных. Эти механизмы позволяют гибко настраивать сборку в зависимости от окружения, операционной системы или пользовательских условий, а также безопасно управлять конфиденциальными данными.


Профили: структура, активация, условия

Профили в Maven позволяют определять альтернативные конфигурации сборки, которые активируются при выполнении определенных условий. Они задаются в файле POM.xml в секции <profiles> или в файле settings.xml. Профили используются для настройки зависимостей, плагинов, свойств или ресурсов в зависимости от окружения (например, разработка, тестирование, продакшен).


Структура профиля
Профиль определяется в <profile> и может включать те же элементы, что и основной POM-файл: <dependencies>, <plugins>, <properties>, <build> и т.д.

Пример:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>development</env>
</properties>
<dependencies>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.7.1</version>
</dependency>
</dependencies>
</profile>
</profiles>


В памяти Maven загружает все профили из POM.xml и settings.xml в объектную модель проекта (POM model) во время инициализации. Активные профили объединяются с основной конфигурацией, создавая итоговую модель сборки. Это увеличивает потребление памяти, особенно если профили содержат сложные конфигурации или множество зависимостей.

Активация профилей

Профили активируются следующими способами:

Явная активация через командную строку:
mvn package -Pdev

Флаг -P указывает идентификатор профиля (id). Можно активировать несколько профилей: -Pdev,test.


Автоматическая активация по условиям:
Профили могут активироваться автоматически на основе условий, заданных в секции <activation>. Maven проверяет эти условия во время загрузки POM-файла, что требует дополнительных вычислений и памяти для оценки.


Активация по системным переменным
Профиль активируется, если указанная системная переменная (-Dkey=value) присутствует или имеет определенное значение:
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>production</value>
</property>
</activation>
</profile>


Запуск:
mvn package -Denv=production

Maven загружает системные свойства в память через System.getProperties() и сравнивает их с условиями активации. Это минимально нагружает память, так как свойства уже доступны в JVM.


Активация по операционной системе
Профиль активируется в зависимости от операционной системы, определенной через параметры os.name, os.family, os.arch или os.version:
<profile>
<id>windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
</profile>


Maven использует API System.getProperty("os.name") для проверки ОС, что не требует значительных ресурсов памяти, так как информация об ОС уже доступна JVM.


#Java #middle #Maven #Profiles #Settings #m2
👍3
Активация по наличию файла
Профиль активируется, если указанный файл существует (или отсутствует):
<profile>
<id>local-config</id>
<activation>
<file>
<exists>${basedir}/local-config.properties</exists>
</file>
</activation>
</profile>


Maven выполняет файловую проверку через API java.io.File, что требует минимальных ресурсов, но может замедлить инициализацию при большом количестве профилей с проверками файлов.

Другие условия
JDK: Активация по версии Java (<jdk>).
Property absence: Активация, если свойство отсутствует (<property><name>!key</name></property>).
Default activation: Профиль может быть активен по умолчанию (<activation><activeByDefault>true</activeByDefault></activation>).


В памяти
Maven хранит список всех профилей и их условия. При загрузке проекта Maven оценивает условия для каждого профиля, создавая временные объекты для хранения результатов проверки. Если профиль активируется, его конфигурация объединяется с основной POM-моделью, что может увеличить объем памяти, особенно в многомодульных проектах.


settings.xml: Локальный и глобальный

Файл settings.xml определяет глобальные или пользовательские настройки Maven, такие как репозитории, прокси, серверы и профили.

Существует два уровня settings.xml:
Глобальный: Расположен в $MAVEN_HOME/conf/settings.xml (обычно в директории установки Maven). Применяется ко всем пользователям системы.
Локальный: Расположен в ~/.m2/settings.xml. Применяется только к текущему пользователю и имеет приоритет над глобальным.


Maven загружает оба файла в память во время инициализации, создавая объектную модель настроек (Settings object). Локальный settings.xml переопределяет глобальный. Если файл отсутствует, Maven использует значения по умолчанию (например, Maven Central в качестве репозитория).


Основные элементы settings.xml
<mirrors>: Позволяет перенаправлять запросы к репозиториям на зеркала для ускорения загрузки или обхода ограничений. Пример:
<mirrors>
<mirror>
<id>central-mirror</id>
<url>https://repo.example.com/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>

Maven загружает конфигурацию зеркал в память и использует ее при разрешении зависимостей, что минимально влияет на потребление ресурсов.


<proxies>: Настраивает прокси для доступа к удаленным репозиториям. Пример:
<proxies>
<proxy>
<id>example-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.example.com</host>
<port>8080</port>
</proxy>
</proxies>

Конфигурация прокси загружается в память как часть объекта Settings, что не требует значительных ресурсов.


<servers>: Хранит учетные данные для доступа к защищенным репозиториям. Пример:
<servers>
<server>
<id>nexus</id>
<username>user</username>
<password>pass</password>
</server>
</servers>

Maven загружает учетные данные в память, но они могут быть зашифрованы для безопасности (см. ниже).


<profiles>: Определяет профили, аналогичные профилям в POM.xml, но на уровне настроек. Они применяются ко всем проектам пользователя. Пример:
<profiles>
<profile>
<id>custom-repo</id>
<repositories>
<repository>
<id>nexus</id>
<url>https://nexus.example.com/repository/maven-public/</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>custom-repo</activeProfile>
</activeProfiles>


В памяти Maven объединяет настройки из settings.xml с моделью POM, создавая единую конфигурацию. Это увеличивает объем памяти, особенно если settings.xml содержит множество профилей или репозиториев.


#Java #middle #Maven #Profiles #Settings #m2
👍3
Переменные

Maven поддерживает несколько типов переменных, которые используются для динамической настройки конфигурации.

User-defined ${} переменные
Пользовательские переменные определяются в <properties> в POM.xml или settings.xml.
<properties>
<java.version>11</java.version>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

Переменные загружаются в память как часть POM-модели или объекта Settings. Maven заменяет ${} на значения во время парсинга, что требует минимальных ресурсов, так как это операция на уровне строк.


Environment variables

Переменные окружения (например, JAVA_HOME, PATH) доступны через ${env.VARIABLE_NAME}.
<properties>
<java.home>${env.JAVA_HOME}</java.home>
</properties>

Maven получает переменные окружения через System.getenv(), что не нагружает память, так как данные уже доступны JVM.


System properties (-D)

Системные свойства задаются через флаг -D в командной строке:

mvn package -Denv=production


Они доступны в POM.xml через ${propertyName}.
<properties>
<env>${env}</env>
</properties>

Системные свойства загружаются в память через System.getProperties(). Они имеют приоритет над переменными из POM.xml или settings.xml.


Переменные из settings.xml и POM
settings.xml: Переменные задаются в <properties> внутри профилей или глобально. Они применяются ко всем проектам.
POM.xml: Переменные в <properties> применяются только к текущему проекту или наследуются дочерними модулями.


Maven объединяет все переменные в единую модель свойств в памяти. Порядок приоритета: системные свойства (-D) > переменные окружения > свойства из POM.xml > свойства из settings.xml. Это требует дополнительных вычислений для разрешения конфликтов имен переменных.


#Java #middle #Maven #Profiles #Settings #m2
👍3