Типы миграций и версионирование в Flyway
1. Структура SQL-миграций
Flyway классифицирует SQL-миграции по префиксам в именах файлов, определяя их поведение при выполнении.
1.1. Именование файлов
Версионные миграции (Versioned)
Префикс V + версия + описание:
Пример:
Повторяемые миграции (Repeatable)
Префикс R + описание:
Пример:
2. Java-миграции
Позволяют описывать миграции на Java для сложной логики, недоступной в SQL.
2.1. Реализация интерфейсов
JdbcMigration (устаревший):
JavaMigration (рекомендуемый):
2.2. Правила
Классы должны находиться в classpath (обычно src/main/java/db/migration).
Имя класса соответствует имени файла SQL-миграции (например, V2__InsertTestData.java).
3. Правила версионирования
3.1. Семантическое версионирование
Рекомендуемый формат версии:
Пример:
Преимущества:
Понятная история изменений.
Совместимость с Semantic Versioning.
3.2. Откат изменений
Flyway не поддерживает автоматический откат. Альтернативы:
Новая миграция для отмены изменений:
Callbacks (SQL-хуки):
Скрипты beforeMigrate/afterMigrate для резервного копирования.
Важно: Не изменяйте уже примененные миграции — это нарушит целостность flyway_schema_history.
4. Примеры
4.1. SQL-миграции
4.2. Java-миграция
#Java #middle #Flyway
1. Структура SQL-миграций
Flyway классифицирует SQL-миграции по префиксам в именах файлов, определяя их поведение при выполнении.
1.1. Именование файлов
Версионные миграции (Versioned)
Префикс V + версия + описание:
V<Версия>__<Описание>.sql
Пример:
-- V1__Create_users_table.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
Повторяемые миграции (Repeatable)
Префикс R + описание:
R__<Описание>.sql
Пример:
-- R__Update_user_view.sql
CREATE OR REPLACE VIEW user_view AS
SELECT id, username FROM users;
2. Java-миграции
Позволяют описывать миграции на Java для сложной логики, недоступной в SQL.
2.1. Реализация интерфейсов
JdbcMigration (устаревший):
public class V2__InsertTestData implements JdbcMigration {
@Override
public void migrate(Connection connection) throws Exception {
try (Statement stmt = connection.createStatement()) {
stmt.execute("INSERT INTO users (username) VALUES ('admin')");
}
}
}
JavaMigration (рекомендуемый):
public class V3__AddAdminUser implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (Statement stmt = context.getConnection().createStatement()) {
stmt.execute("INSERT INTO users (username) VALUES ('superuser')");
}
}
}
2.2. Правила
Классы должны находиться в classpath (обычно src/main/java/db/migration).
Имя класса соответствует имени файла SQL-миграции (например, V2__InsertTestData.java).
3. Правила версионирования
3.1. Семантическое версионирование
Рекомендуемый формат версии:
V<Мажор>.<Минор>.<Патч>__<Описание>.sql
Пример:
-- V1.2.3__Fix_email_constraint.sql
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Преимущества:
Понятная история изменений.
Совместимость с Semantic Versioning.
3.2. Откат изменений
Flyway не поддерживает автоматический откат. Альтернативы:
Новая миграция для отмены изменений:
-- V3__Drop_users_table.sql
DROP TABLE users;
Callbacks (SQL-хуки):
Скрипты beforeMigrate/afterMigrate для резервного копирования.
Важно: Не изменяйте уже примененные миграции — это нарушит целостность flyway_schema_history.
4. Примеры
4.1. SQL-миграции
-- V1__Initial_schema.sql
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
);
-- R__Update_view.sql
CREATE OR REPLACE VIEW active_users AS
SELECT * FROM users WHERE deleted_at IS NULL;
4.2. Java-миграция
public class V4__EncryptPasswords implements JavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (PreparedStatement ps = context.getConnection()
.prepareStatement("UPDATE users SET password = encrypt(password)")) {
ps.executeUpdate();
}
}
}
#Java #middle #Flyway
Интеграция Flyway с инструментами
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
Команды:
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
6. Пропуск миграций в тестах
В application-test.yml:
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
Классовый путь + файловая система:
#Java #middle #Flyway
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>9.22.0</version>
<configuration>
<url>jdbc:postgresql://localhost:5432/mydb</url>
<user>postgres</user>
<password>password</password>
<locations>
<location>classpath:db/migration</location>
</locations>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
mvn flyway:migrate # Применить миграции
mvn flyway:info # Показать статус
mvn flyway:clean # Очистить БД (удалить все объекты)
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
plugins {
id "org.flywaydb.flyway" version "9.22.0"
}
flyway {
url = 'jdbc:postgresql://localhost:5432/mydb'
user = 'postgres'
password = 'password'
locations = ['classpath:db/migration']
}
dependencies {
flywayRuntime 'org.postgresql:postgresql:42.6.0'
}
Команды:
gradle flywayMigrate # Применить миграции
gradle flywayInfo # Показать статус
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: password
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true # Игнорировать существующую БД
validate-on-migrate: false # Отключить валидацию (для dev)
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
-- beforeMigrate.sql
CREATE TABLE IF NOT EXISTS _flyway_audit (
operation VARCHAR(20),
timestamp TIMESTAMP
);
INSERT INTO _flyway_audit VALUES ('migration_started', NOW());
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
<!-- Maven -->
<location>filesystem:${project.basedir}/../migrations/src/main/resources/db/migration</location>
// Gradle
locations = ['filesystem:../migrations/src/main/resources/db/migration']
6. Пропуск миграций в тестах
В application-test.yml:
spring:
flyway:
enabled: false
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
spring:
flyway:
locations: s3://my-bucket/db/migration
Классовый путь + файловая система:
locations: classpath:db/migration, filesystem:/opt/migrations
#Java #middle #Flyway
Best Practices и расширенные сценарии работы с Flyway
1. Организация миграций
1.1. Разделение миграций по окружениям
Проблема:
Разные БД для dev/test/prod могут требовать специфичных скриптов (например, тестовые данные только для dev).
Решение:
Структура папок:
Настройка application.yml для dev:
1.2. Работа с существующей БД (baseline)
Проблема:
Flyway ожидает пустую БД или таблицу flyway_schema_history. Если БД уже используется, требуется инициализация.
Решение:
Включить baseline-on-migrate:
Вручную через CLI:
Важно:
После baseline миграции с версией ≤ baselineVersion игнорируются.
2. Тестирование миграций
2.1. Интеграция с Testcontainers + JUnit
Цель:
Проверить, что миграции применяются без ошибок в изолированной БД.
Пример теста (Java + JUnit 5):
Что проверяем:
Применение всех миграций без исключений.
Соответствие схемы ожиданиям (можно добавить проверку через DataSource).
3. Работа в команде
3.1. Именование файлов
Правила:
Уникальность версий:
Используйте дату + порядковый номер: V20240315-1__Add_users_table.sql.
Описательные имена:
Плохо: V1__Changes.sql.
Хорошо: V20240315-2__Alter_users_add_email.sql.
3.2. Запрет изменения примененных скриптов
Проблема:
Изменение уже выполненного скрипта приводит к ошибке:
Решение:
Никогда не изменять содержимое V*-файлов после их применения.
Для исправлений:
Создать новую миграцию с корректировкой:
Если критично, использовать flyway repair (пересчитывает контрольные суммы).
Исключение:
R__-миграции (повторяемые) можно изменять — они переприменяются при изменениях.
4. Расширенные сценарии
4.1. Миграции для нескольких схем БД
Настройка:
4.2. Шаблонизация SQL
Проблема:
Разные SQL-синтаксисы для PostgreSQL/Oracle.
Решение (через Maven/Gradle):
Используйте placeholders в pom.xml:
В SQL:
4.3. Откаты (безопасная альтернатива)
Тактика:
Для деструктивных изменений (DROP, DELETE) создавать "обратные" миграции:
#Java #middle #Flyway
1. Организация миграций
1.1. Разделение миграций по окружениям
Проблема:
Разные БД для dev/test/prod могут требовать специфичных скриптов (например, тестовые данные только для dev).
Решение:
Структура папок:
db/
migration/
dev/
V1__Dev_only_data.sql
prod/
V1__Prod_indexes.sql
common/
V1__Base_schema.sql
Настройка application.yml для dev:
spring:
flyway:
locations: classpath:db/migration/common, classpath:db/migration/dev
1.2. Работа с существующей БД (baseline)
Проблема:
Flyway ожидает пустую БД или таблицу flyway_schema_history. Если БД уже используется, требуется инициализация.
Решение:
Включить baseline-on-migrate:
spring:
flyway:
baseline-on-migrate: true
baseline-version: 1.0 # Версия, с которой начнется контроль
Вручную через CLI:
flyway baseline -baselineVersion="1.0"
Важно:
После baseline миграции с версией ≤ baselineVersion игнорируются.
2. Тестирование миграций
2.1. Интеграция с Testcontainers + JUnit
Цель:
Проверить, что миграции применяются без ошибок в изолированной БД.
Пример теста (Java + JUnit 5):
import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers
public class FlywayMigrationTest {
@Container
private static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:15");
@Test
void testMigrations() {
Flyway flyway = Flyway.configure()
.dataSource(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
)
.load();
flyway.migrate(); // Упадет, если есть ошибки
}
}
Что проверяем:
Применение всех миграций без исключений.
Соответствие схемы ожиданиям (можно добавить проверку через DataSource).
3. Работа в команде
3.1. Именование файлов
Правила:
Уникальность версий:
Используйте дату + порядковый номер: V20240315-1__Add_users_table.sql.
Описательные имена:
Плохо: V1__Changes.sql.
Хорошо: V20240315-2__Alter_users_add_email.sql.
3.2. Запрет изменения примененных скриптов
Проблема:
Изменение уже выполненного скрипта приводит к ошибке:
Validate failed: Migration checksum mismatch for V1__Create_table.sql
Решение:
Никогда не изменять содержимое V*-файлов после их применения.
Для исправлений:
Создать новую миграцию с корректировкой:
-- V20240315-3__Fix_users_table.sql
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Если критично, использовать flyway repair (пересчитывает контрольные суммы).
Исключение:
R__-миграции (повторяемые) можно изменять — они переприменяются при изменениях.
4. Расширенные сценарии
4.1. Миграции для нескольких схем БД
Настройка:
spring:
flyway:
schemas: public, audit
default-schema: public
В SQL-файлах укажите схему явно:
sql
-- V1__Create_audit_table.sql
CREATE TABLE audit.logs (
id SERIAL PRIMARY KEY,
message TEXT
);
4.2. Шаблонизация SQL
Проблема:
Разные SQL-синтаксисы для PostgreSQL/Oracle.
Решение (через Maven/Gradle):
Используйте placeholders в pom.xml:
<configuration>
<placeholders>
<table.prefix>${env}</table.prefix>
</placeholders>
</configuration>
В SQL:
CREATE TABLE ${table.prefix}_users (...);
4.3. Откаты (безопасная альтернатива)
Тактика:
Для деструктивных изменений (DROP, DELETE) создавать "обратные" миграции:
-- V5__Drop_users.sql
DROP TABLE users;
-- V6__Restore_users.sql (если нужно откатить)
CREATE TABLE users (...); -- Повторяем структуру из V1
INSERT INTO users (...) SELECT ... FROM backup_users;
Использовать резервные копии перед рискованными операциями.
#Java #middle #Flyway
Архитектура Maven и философия Convention over Configuration
После первого знакомства с Maven важно не просто уметь пользоваться им, а понимать его архитектуру, принципы работы и идеологию. Это особенно критично для тех, кто хочет углубиться в автоматизацию, CI/CD и масштабирование проектов с помощью Maven.
Maven как декларативная модель
Maven основан на декларативной модели сборки: вы описываете, что должно быть сделано, а не как. Это противоположность императивным сборочным системам вроде Ant, где разработчик пишет шаг за шагом скрипты сборки. В Maven центром управления является файл pom.xml — он описывает структуру проекта, зависимости, плагины, цели сборки и метаинформацию.
Архитектура Maven
Архитектура Maven построена вокруг трёх ключевых сущностей:
1. POM (Project Object Model)
POM — сердце проекта. В нем описано всё: от координат артефакта (groupId, artifactId, version) до зависимостей, плагинов, профилей и модулей. POM определяет не только поведение сборки, но и организацию кода, стратегию управления версиями и способы расширения функциональности проекта.
2. Репозитории
Система Maven разделяет репозитории на три уровня:
Локальный (~/.m2/repository) — кеш библиотек и плагинов, уже использованных разработчиком
Центральный (Maven Central) — основной публичный репозиторий.
Удалённые (корпоративные) — приватные хранилища (Nexus, Artifactory и др.).
При разрешении зависимостей Maven сначала ищет артефакт в локальном репозитории, затем — в удалённых.
3. Плагины и цели (goals)
Maven сам по себе — движок исполнения, не знающий, как компилировать, тестировать или архивировать проект. Всё это делают плагины, привязанные к жизненному циклу. Например, maven-compiler-plugin отвечает за компиляцию, а maven-surefire-plugin — за запуск тестов. Каждый плагин состоит из целей (goals), которые выполняются в рамках фаз сборки.
Жизненный цикл сборки
Основой выполнения в Maven является жизненный цикл сборки (Build Lifecycle) — предопределённая последовательность фаз.
Есть три основных цикла:
default — основной, включает: compile, test, package, install, deploy.
clean — очищает артефакты: pre-clean, clean, post-clean.
site — генерирует документацию: site, site-deploy.
Maven всегда выполняет все фазы до указанной. То есть mvn install запустит validate, compile, test, package, verify, install.
Convention over Configuration
Одной из ключевых идей Maven является принцип «Конвенция важнее конфигурации» (Convention over Configuration):
Maven ожидает, что структура проекта будет стандартной:
Артефакт будет упакован как jar (если не указано иное).
Папки ресурсов и тестов тоже стандартны.
Это означает, что вам не нужно конфигурировать то, что уже стандартизировано. Но при этом Maven предоставляет гибкость, позволяя переопределять любую часть стандартной логики при необходимости.
Maven и расширяемость
Благодаря своей архитектуре, Maven легко адаптируется под различные сценарии.
Расширение происходит через:
Подключение плагинов.
Наследование и агрегацию POM'ов.
Создание собственных плагинов и Mojo.
Подключение профилей и переменных окружения.
Именно такая расширяемость делает Maven удобным не только для простых библиотек, но и для масштабных корпоративных решений.
#Java #middle #Maven
После первого знакомства с Maven важно не просто уметь пользоваться им, а понимать его архитектуру, принципы работы и идеологию. Это особенно критично для тех, кто хочет углубиться в автоматизацию, CI/CD и масштабирование проектов с помощью Maven.
Maven как декларативная модель
Maven основан на декларативной модели сборки: вы описываете, что должно быть сделано, а не как. Это противоположность императивным сборочным системам вроде Ant, где разработчик пишет шаг за шагом скрипты сборки. В Maven центром управления является файл pom.xml — он описывает структуру проекта, зависимости, плагины, цели сборки и метаинформацию.
Архитектура Maven
Архитектура Maven построена вокруг трёх ключевых сущностей:
1. POM (Project Object Model)
POM — сердце проекта. В нем описано всё: от координат артефакта (groupId, artifactId, version) до зависимостей, плагинов, профилей и модулей. POM определяет не только поведение сборки, но и организацию кода, стратегию управления версиями и способы расширения функциональности проекта.
2. Репозитории
Система Maven разделяет репозитории на три уровня:
Локальный (~/.m2/repository) — кеш библиотек и плагинов, уже использованных разработчиком
Центральный (Maven Central) — основной публичный репозиторий.
Удалённые (корпоративные) — приватные хранилища (Nexus, Artifactory и др.).
При разрешении зависимостей Maven сначала ищет артефакт в локальном репозитории, затем — в удалённых.
3. Плагины и цели (goals)
Maven сам по себе — движок исполнения, не знающий, как компилировать, тестировать или архивировать проект. Всё это делают плагины, привязанные к жизненному циклу. Например, maven-compiler-plugin отвечает за компиляцию, а maven-surefire-plugin — за запуск тестов. Каждый плагин состоит из целей (goals), которые выполняются в рамках фаз сборки.
Жизненный цикл сборки
Основой выполнения в Maven является жизненный цикл сборки (Build Lifecycle) — предопределённая последовательность фаз.
Есть три основных цикла:
default — основной, включает: compile, test, package, install, deploy.
clean — очищает артефакты: pre-clean, clean, post-clean.
site — генерирует документацию: site, site-deploy.
Maven всегда выполняет все фазы до указанной. То есть mvn install запустит validate, compile, test, package, verify, install.
Convention over Configuration
Одной из ключевых идей Maven является принцип «Конвенция важнее конфигурации» (Convention over Configuration):
Maven ожидает, что структура проекта будет стандартной:
src/
main/java/
test/java/
Артефакт будет упакован как jar (если не указано иное).
Папки ресурсов и тестов тоже стандартны.
Это означает, что вам не нужно конфигурировать то, что уже стандартизировано. Но при этом Maven предоставляет гибкость, позволяя переопределять любую часть стандартной логики при необходимости.
Maven и расширяемость
Благодаря своей архитектуре, Maven легко адаптируется под различные сценарии.
Расширение происходит через:
Подключение плагинов.
Наследование и агрегацию POM'ов.
Создание собственных плагинов и Mojo.
Подключение профилей и переменных окружения.
Именно такая расширяемость делает Maven удобным не только для простых библиотек, но и для масштабных корпоративных решений.
#Java #middle #Maven
Руководство по POM (Project Object Model) в Maven
POM (Project Object Model) является основой любого Maven-проекта. Файл pom.xml определяет структуру проекта, его зависимости, процесс сборки и другие аспекты, необходимые для управления жизненным циклом проекта. Этот документ представляет собой XML-файл, который Maven интерпретирует для создания модели проекта в памяти.
Основные теги
Основные теги pom.xml формируют базовую идентификацию и структуру проекта. Они обязательны или критически важны для корректной работы Maven.
<project>: Корневой элемент каждого pom.xml. Он определяет пространство имен XML (xmlns) и схему (xsi:schemaLocation), чтобы Maven мог валидировать файл. Все остальные элементы являются дочерними для <project>. В памяти Maven создает объект Project, который хранит всю информацию о проекте, включая зависимости, плагины и настройки сборки.
<modelVersion>: Указывает версию модели POM, используемой в файле. На момент 2025 года стандартной является версия 4.0.0. Этот тег необходим, так как Maven использует его для определения правил парсинга и совместимости. Неправильная версия приведет к ошибке парсинга.
<groupId>: Уникальный идентификатор группы, к которой относится проект. Обычно это доменное имя компании или организации в обратном порядке (например, com.example). В памяти Maven использует groupId как часть координат для идентификации артефакта в репозитории.
<artifactId>: Уникальное имя артефакта внутри группы. Это название проекта или модуля (например, my-app). Вместе с groupId и version формирует уникальные координаты артефакта.
<version>: Версия проекта. Следует семантическому версионированию (например, 1.0.0-SNAPSHOT). Maven использует версию для управления артефактами в локальном и удаленных репозиториях. Суффикс SNAPSHOT указывает на нестабильную версию, что влияет на поведение кэширования.
<packaging>: Определяет тип выходного артефакта (например, jar, war, pom). По умолчанию — jar. Этот тег влияет на жизненный цикл сборки, так как Maven выбирает соответствующие плагины и цели (goals) для обработки. Например, для war подключается плагин maven-war-plugin.
Эти теги формируют минимальный pom.xml. Maven парсит их в объектную модель, которая хранится в памяти JVM во время выполнения. Объектная модель включает org.apache.maven.model.Model, где каждый тег маппится на соответствующее поле или коллекцию. Например, groupId, artifactId и version объединяются в уникальный ключ артефакта.
Расширенные теги
Расширенные теги добавляют метаданные, улучшающие документацию и управление проектом. Они необязательны, но полезны в корпоративных средах.
<name>: Человекочитаемое название проекта. Используется в отчетах и документации, генерируемых Maven (например, через maven-site-plugin). Не влияет на логику сборки, но хранится в метаданных артефакта.
<description>: Описание проекта. Как и <name>, используется для документации. Maven включает это поле в метаданные артефакта, которые публикуются в репозиторий.
<url>: URL проекта, например, сайт или репозиторий. Используется в документации и для генерации ссылок в отчетах.
<inceptionYear>: Год создания проекта. Это поле чисто информационное, хранится в метаданных.
<organization>: Содержит информацию об организации, включая <name> и <url>. Используется для единообразной документации в крупных проектах.
Эти теги не влияют на процесс сборки, но добавляются в файл метаданных артефакта (META-INF/maven/groupId/artifactId/pom.properties), который создается при упаковке. В памяти они хранятся как часть объекта Model, но не участвуют в логике выполнения.
#Java #middle #Maven #pom
POM (Project Object Model) является основой любого Maven-проекта. Файл pom.xml определяет структуру проекта, его зависимости, процесс сборки и другие аспекты, необходимые для управления жизненным циклом проекта. Этот документ представляет собой XML-файл, который Maven интерпретирует для создания модели проекта в памяти.
Основные теги
Основные теги pom.xml формируют базовую идентификацию и структуру проекта. Они обязательны или критически важны для корректной работы Maven.
<project>: Корневой элемент каждого pom.xml. Он определяет пространство имен XML (xmlns) и схему (xsi:schemaLocation), чтобы Maven мог валидировать файл. Все остальные элементы являются дочерними для <project>. В памяти Maven создает объект Project, который хранит всю информацию о проекте, включая зависимости, плагины и настройки сборки.
<modelVersion>: Указывает версию модели POM, используемой в файле. На момент 2025 года стандартной является версия 4.0.0. Этот тег необходим, так как Maven использует его для определения правил парсинга и совместимости. Неправильная версия приведет к ошибке парсинга.
<groupId>: Уникальный идентификатор группы, к которой относится проект. Обычно это доменное имя компании или организации в обратном порядке (например, com.example). В памяти Maven использует groupId как часть координат для идентификации артефакта в репозитории.
<artifactId>: Уникальное имя артефакта внутри группы. Это название проекта или модуля (например, my-app). Вместе с groupId и version формирует уникальные координаты артефакта.
<version>: Версия проекта. Следует семантическому версионированию (например, 1.0.0-SNAPSHOT). Maven использует версию для управления артефактами в локальном и удаленных репозиториях. Суффикс SNAPSHOT указывает на нестабильную версию, что влияет на поведение кэширования.
<packaging>: Определяет тип выходного артефакта (например, jar, war, pom). По умолчанию — jar. Этот тег влияет на жизненный цикл сборки, так как Maven выбирает соответствующие плагины и цели (goals) для обработки. Например, для war подключается плагин maven-war-plugin.
Эти теги формируют минимальный pom.xml. Maven парсит их в объектную модель, которая хранится в памяти JVM во время выполнения. Объектная модель включает org.apache.maven.model.Model, где каждый тег маппится на соответствующее поле или коллекцию. Например, groupId, artifactId и version объединяются в уникальный ключ артефакта.
Расширенные теги
Расширенные теги добавляют метаданные, улучшающие документацию и управление проектом. Они необязательны, но полезны в корпоративных средах.
<name>: Человекочитаемое название проекта. Используется в отчетах и документации, генерируемых Maven (например, через maven-site-plugin). Не влияет на логику сборки, но хранится в метаданных артефакта.
<description>: Описание проекта. Как и <name>, используется для документации. Maven включает это поле в метаданные артефакта, которые публикуются в репозиторий.
<url>: URL проекта, например, сайт или репозиторий. Используется в документации и для генерации ссылок в отчетах.
<inceptionYear>: Год создания проекта. Это поле чисто информационное, хранится в метаданных.
<organization>: Содержит информацию об организации, включая <name> и <url>. Используется для единообразной документации в крупных проектах.
Эти теги не влияют на процесс сборки, но добавляются в файл метаданных артефакта (META-INF/maven/groupId/artifactId/pom.properties), который создается при упаковке. В памяти они хранятся как часть объекта Model, но не участвуют в логике выполнения.
#Java #middle #Maven #pom
Работа с <properties>
Тег <properties> позволяет определять пользовательские переменные, которые можно использовать в других частях pom.xml. Это улучшает читаемость и упрощает управление конфигурацией.
Пример:
Переменные используются через синтаксис ${property.name}.
Например:
Maven при парсинге pom.xml заменяет все ${...} на соответствующие значения. Это происходит на этапе создания модели в памяти. Если свойство не найдено, Maven пытается использовать системные свойства JVM или переменные окружения. Если и это не удается, сборка завершится ошибкой.
Свойства также могут быть переопределены через командную строку:
В памяти свойства хранятся в объекте Properties внутри модели Model. Они доступны всем плагинам и процессам сборки.
Важный нюанс: свойства не наследуются автоматически в дочерних модулях, если они определены в <properties> родительского POM. Для этого нужно использовать <dependencyManagement> или <pluginManagement>.
<dependencies>: Управление зависимостями
Тег <dependencies> определяет библиотеки, необходимые проекту. Каждая зависимость описывается тегом <dependency> с обязательными полями groupId, artifactId и version.
Scope'ы зависимостей
Атрибут <scope> определяет область применения зависимости:
compile: Зависимость доступна для компиляции, тестирования и выполнения. Включается в итоговый артефакт (например, в jar). Это значение по умолчанию.
provided: Зависимость нужна для компиляции, но предоставляется средой выполнения (например, сервлет API в контейнере). Не включается в итоговый артефакт.
runtime: Зависимость нужна только во время выполнения (например, JDBC-драйвер). Не используется при компиляции.
test: Зависимость нужна только для тестирования (например, JUnit). Не включается в итоговый артефакт.
system: Указывает локальный путь к зависимости через <systemPath>. Используется редко, так как нарушает принцип переносимости.
import: Используется в <dependencyManagement> для импорта зависимостей из другого POM. Не добавляет зависимость напрямую.
Maven при разрешении зависимостей создает граф зависимостей в памяти (используя org.apache.maven.artifact.Artifact). Для каждого артефакта хранится его scope, что влияет на classpath для различных фаз сборки. Например, test зависимости добавляются только в classpath для фазы test.
Exclusions и конфликт зависимостей
Конфликты зависимостей возникают, когда разные версии одной и той же библиотеки включаются через транзитивные зависимости. Maven решает конфликты, выбирая ближайшую к корню графа версию (стратегия "nearest wins"). Это может привести к проблемам, если выбранная версия несовместима.
Для исключения нежелательных транзитивных зависимостей используется тег <exclusions>:
В памяти Maven модифицирует граф зависимостей, удаляя исключенные артефакты. Это происходит на этапе разрешения зависимостей (dependency:resolve).
Для диагностики конфликтов полезна команда:
#Java #middle #Maven #pom
Тег <properties> позволяет определять пользовательские переменные, которые можно использовать в других частях pom.xml. Это улучшает читаемость и упрощает управление конфигурацией.
Пример:
<properties>
<java.version>11</java.version>
<spring.version>5.3.10</spring.version>
</properties>
Переменные используются через синтаксис ${property.name}.
Например:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
Maven при парсинге pom.xml заменяет все ${...} на соответствующие значения. Это происходит на этапе создания модели в памяти. Если свойство не найдено, Maven пытается использовать системные свойства JVM или переменные окружения. Если и это не удается, сборка завершится ошибкой.
Свойства также могут быть переопределены через командную строку:
mvn clean install -Djava.version=17
В памяти свойства хранятся в объекте Properties внутри модели Model. Они доступны всем плагинам и процессам сборки.
Важный нюанс: свойства не наследуются автоматически в дочерних модулях, если они определены в <properties> родительского POM. Для этого нужно использовать <dependencyManagement> или <pluginManagement>.
<dependencies>: Управление зависимостями
Тег <dependencies> определяет библиотеки, необходимые проекту. Каждая зависимость описывается тегом <dependency> с обязательными полями groupId, artifactId и version.
Scope'ы зависимостей
Атрибут <scope> определяет область применения зависимости:
compile: Зависимость доступна для компиляции, тестирования и выполнения. Включается в итоговый артефакт (например, в jar). Это значение по умолчанию.
provided: Зависимость нужна для компиляции, но предоставляется средой выполнения (например, сервлет API в контейнере). Не включается в итоговый артефакт.
runtime: Зависимость нужна только во время выполнения (например, JDBC-драйвер). Не используется при компиляции.
test: Зависимость нужна только для тестирования (например, JUnit). Не включается в итоговый артефакт.
system: Указывает локальный путь к зависимости через <systemPath>. Используется редко, так как нарушает принцип переносимости.
import: Используется в <dependencyManagement> для импорта зависимостей из другого POM. Не добавляет зависимость напрямую.
Maven при разрешении зависимостей создает граф зависимостей в памяти (используя org.apache.maven.artifact.Artifact). Для каждого артефакта хранится его scope, что влияет на classpath для различных фаз сборки. Например, test зависимости добавляются только в classpath для фазы test.
Exclusions и конфликт зависимостей
Конфликты зависимостей возникают, когда разные версии одной и той же библиотеки включаются через транзитивные зависимости. Maven решает конфликты, выбирая ближайшую к корню графа версию (стратегия "nearest wins"). Это может привести к проблемам, если выбранная версия несовместима.
Для исключения нежелательных транзитивных зависимостей используется тег <exclusions>:
<dependency>
<groupId>org.example</groupId>
<artifactId>lib-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.unwanted</groupId>
<artifactId>unwanted-lib</artifactId>
</exclusion>
</exclusions>
</dependency>
В памяти Maven модифицирует граф зависимостей, удаляя исключенные артефакты. Это происходит на этапе разрешения зависимостей (dependency:resolve).
Для диагностики конфликтов полезна команда:
mvn dependency:tree
#Java #middle #Maven #pom
<dependencyManagement>: Централизованный контроль зависимостей
Тег <dependencyManagement> позволяет определять версии и настройки зависимостей, которые будут использоваться в проекте или его модулях. Это особенно полезно в многомодульных проектах.
Пример:
Зависимости из <dependencyManagement> не добавляются в проект автоматически. Они активируются только при указании groupId и artifactId в <dependencies> без версии. Это позволяет централизовать управление версиями в родительском POM.
В памяти Maven хранит эти зависимости в объекте DependencyManagement, который используется для разрешения версий при парсинге дочерних POM. Это снижает риск конфликтов версий в многомодульных проектах.
<build> и <plugins>
Тег <build> определяет процесс сборки проекта. Он включает настройки каталогов, плагинов и другие параметры.
Основные дочерние элементы:
<sourceDirectory>: Путь к исходному коду (по умолчанию src/main/java).
<testSourceDirectory>: Путь к тестам (по умолчанию src/test/java).
<resources>: Ресурсы, включаемые в артефакт.
<plugins>: Список плагинов для выполнения задач.
Пример плагина:
Каждый плагин привязан к фазам жизненного цикла Maven (например, compile, test, package). Плагины выполняются в JVM как отдельные классы, загружаемые через собственный класслоадер Maven. В памяти создается объект Plugin, содержащий конфигурацию и привязки к фазам.
Тег <pluginManagement> работает аналогично <dependencyManagement>, позволяя задавать конфигурацию плагинов для наследования в дочерних модулях.
<profiles>: Профили сборки
Профили позволяют настраивать сборку под разные окружения (например, dev, prod). Тег <profiles> содержит список <profile>.
Пример:
Профиль активируется через:
Командную строку: mvn clean install -Pdev.
Условия в <activation> (например, по OS, JDK или наличию файла).
Maven при парсинге объединяет активный профиль с основным pom.xml. Это происходит в памяти, где профиль мержится с моделью Model. Если несколько профилей активны, они применяются в порядке определения.
<repositories> и <pluginRepositories>
Теги <repositories> и <pluginRepositories> указывают, где Maven должен искать зависимости и плагины. По умолчанию используется центральный репозиторий Maven (https://repo.maven.apache.org/maven2).
Пример:
Maven загружает артефакты сначала из локального репозитория (~/.m2/repository), затем из указанных репозиториев. В памяти создается список объектов Repository, которые используются резолвером зависимостей.
#Java #middle #Maven #pom
Тег <dependencyManagement> позволяет определять версии и настройки зависимостей, которые будут использоваться в проекте или его модулях. Это особенно полезно в многомодульных проектах.
Пример:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.10</version>
</dependency>
</dependencies>
</dependencyManagement>
Зависимости из <dependencyManagement> не добавляются в проект автоматически. Они активируются только при указании groupId и artifactId в <dependencies> без версии. Это позволяет централизовать управление версиями в родительском POM.
В памяти Maven хранит эти зависимости в объекте DependencyManagement, который используется для разрешения версий при парсинге дочерних POM. Это снижает риск конфликтов версий в многомодульных проектах.
<build> и <plugins>
Тег <build> определяет процесс сборки проекта. Он включает настройки каталогов, плагинов и другие параметры.
Основные дочерние элементы:
<sourceDirectory>: Путь к исходному коду (по умолчанию src/main/java).
<testSourceDirectory>: Путь к тестам (по умолчанию src/test/java).
<resources>: Ресурсы, включаемые в артефакт.
<plugins>: Список плагинов для выполнения задач.
Пример плагина:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
Каждый плагин привязан к фазам жизненного цикла Maven (например, compile, test, package). Плагины выполняются в JVM как отдельные классы, загружаемые через собственный класслоадер Maven. В памяти создается объект Plugin, содержащий конфигурацию и привязки к фазам.
Тег <pluginManagement> работает аналогично <dependencyManagement>, позволяя задавать конфигурацию плагинов для наследования в дочерних модулях.
<profiles>: Профили сборки
Профили позволяют настраивать сборку под разные окружения (например, dev, prod). Тег <profiles> содержит список <profile>.
Пример:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>development</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>production</env>
</properties>
</profile>
</profiles>
Профиль активируется через:
Командную строку: mvn clean install -Pdev.
Условия в <activation> (например, по OS, JDK или наличию файла).
Maven при парсинге объединяет активный профиль с основным pom.xml. Это происходит в памяти, где профиль мержится с моделью Model. Если несколько профилей активны, они применяются в порядке определения.
<repositories> и <pluginRepositories>
Теги <repositories> и <pluginRepositories> указывают, где Maven должен искать зависимости и плагины. По умолчанию используется центральный репозиторий Maven (https://repo.maven.apache.org/maven2).
Пример:
<repositories>
<repository>
<id>custom-repo</id>
<url>https://repo.example.com</url>
</repository>
</repositories>
Maven загружает артефакты сначала из локального репозитория (~/.m2/repository), затем из указанных репозиториев. В памяти создается список объектов Repository, которые используются резолвером зависимостей.
#Java #middle #Maven #pom
Parent POM'ы и наследование
Родительский POM позволяет централизовать конфигурацию для нескольких проектов.
Дочерний проект ссылается на родительский через <parent>:
Maven при парсинге загружает родительский POM и объединяет его с дочерним.
Наследуются:
- <dependencyManagement> и <pluginManagement>.
- <properties>.
- <repositories> и <pluginRepositories>.
В памяти создается композитная модель Model, где дочерний POM имеет приоритет над родительским. Это позволяет переопределять настройки. Однако <dependencies> и <plugins> не наследуются напрямую, чтобы избежать нежелательных включений.
Нюансы работы в памяти
Maven при запуске создает в JVM объектную модель проекта:
Парсинг pom.xml с помощью библиотеки plexus-utils и создание объекта org.apache.maven.model.Model.
Разрешение переменных ${...} с учетом <properties>, системных свойств и окружения.
Построение графа зависимостей с использованием Aether (библиотека для работы с репозиториями).
Создание плана выполнения (execution plan), где плагины привязываются к фазам жизненного цикла.
Каждый плагин выполняется в изолированном класслоадере, чтобы избежать конфликтов зависимостей. Локальный репозиторий (~/.m2/repository) кэширует артефакты, минимизируя сетевые запросы. Для SNAPSHOT-версий Maven периодически проверяет обновления в удаленных репозиториях.
#Java #middle #Maven #Pom
Родительский POM позволяет централизовать конфигурацию для нескольких проектов.
Дочерний проект ссылается на родительский через <parent>:
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0</version>
</parent>
Maven при парсинге загружает родительский POM и объединяет его с дочерним.
Наследуются:
- <dependencyManagement> и <pluginManagement>.
- <properties>.
- <repositories> и <pluginRepositories>.
В памяти создается композитная модель Model, где дочерний POM имеет приоритет над родительским. Это позволяет переопределять настройки. Однако <dependencies> и <plugins> не наследуются напрямую, чтобы избежать нежелательных включений.
Нюансы работы в памяти
Maven при запуске создает в JVM объектную модель проекта:
Парсинг pom.xml с помощью библиотеки plexus-utils и создание объекта org.apache.maven.model.Model.
Разрешение переменных ${...} с учетом <properties>, системных свойств и окружения.
Построение графа зависимостей с использованием Aether (библиотека для работы с репозиториями).
Создание плана выполнения (execution plan), где плагины привязываются к фазам жизненного цикла.
Каждый плагин выполняется в изолированном класслоадере, чтобы избежать конфликтов зависимостей. Локальный репозиторий (~/.m2/repository) кэширует артефакты, минимизируя сетевые запросы. Для SNAPSHOT-версий Maven периодически проверяет обновления в удаленных репозиториях.
#Java #middle #Maven #Pom
Жизненный цикл Maven: Полное понимание фаз и процессов
Maven — это мощный инструмент управления сборкой проектов, ядро которого составляет концепция жизненного цикла. Жизненный цикл Maven определяет последовательность фаз, через которые проходит проект во время сборки, обеспечивая предсказуемость и структурированность процесса.
Структура жизненного цикла Maven
Maven использует три основных жизненных цикла, каждый из которых представляет собой набор фаз, выполняемых последовательно для достижения определенной цели. Эти циклы — Clean, Default (Build) и Site — охватывают различные аспекты работы с проектом, от очистки до развертывания документации.
Clean Lifecycle
Жизненный цикл Clean отвечает за удаление артефактов, созданных в процессе предыдущих сборок, чтобы обеспечить чистую рабочую среду.
Он состоит из трех фаз:
pre-clean: Подготовка к очистке. На этой фазе выполняются предварительные действия, такие как завершение незавершенных процессов или освобождение ресурсов. Плагины редко привязаны к этой фазе, но она может использоваться для пользовательских задач, например, для проверки состояния проекта перед очисткой.
clean: Основная фаза очистки. Удаляет директорию target, содержащую скомпилированные классы, JAR-файлы, WAR-файлы и другие артефакты. По умолчанию к этой фазе привязан плагин maven-clean-plugin с целью clean.
post-clean: Завершающие действия после очистки. Эта фаза редко используется, но может быть полезна для выполнения дополнительных операций, таких как логирование или уведомления.
В памяти на этапе Clean происходит освобождение ресурсов, связанных с предыдущими сборками. Maven загружает конфигурацию проекта (POM-файл) в оперативную память, создает объектную модель проекта (POM model), которая хранит метаданные о проекте, зависимостях и плагинах. Во время выполнения clean Maven взаимодействует с файловой системой, удаляя указанные директории, что минимизирует использование памяти, так как не создаются новые артефакты.
Default (Build) Lifecycle
Default — наиболее важный жизненный цикл, охватывающий процесс сборки, тестирования и развертывания артефактов.
Он включает множество фаз, из которых наиболее часто используемые:
validate: Проверяет корректность структуры проекта и наличие всех необходимых ресурсов, таких как POM-файл и зависимости. Maven загружает и валидирует модель POM, проверяя синтаксис и доступность репозиториев.
compile: Компилирует исходный код проекта. По умолчанию используется maven-compiler-plugin, который преобразует Java-файлы в байт-код, сохраняя его в директории target/classes.
test: Выполняет модульные тесты с использованием плагинов, таких как maven-surefire-plugin. Тесты запускаются в изолированной среде, а результаты сохраняются в target/surefire-reports.
package: Создает артефакт (JAR, WAR, EAR и т.д.) на основе скомпилированного кода и ресурсов. Используется, например, maven-jar-plugin для создания JAR-файлов.
verify: Проверяет качество артефакта, выполняя интеграционные тесты или проверки, например, с помощью maven-failsafe-plugin.
install: Устанавливает артефакт в локальный репозиторий (~/.m2/repository), делая его доступным для других локальных проектов.
deploy: Разворачивает артефакт в удаленный репозиторий для общего использования. Используется maven-deploy-plugin.
Каждая фаза Default цикла добавляет новые данные в директорию target, что увеличивает объем используемой памяти. Например, во время компиляции Maven загружает в память исходные файлы, зависимости и настройки компилятора. Плагины, такие как maven-compiler-plugin, создают временные структуры данных для хранения промежуточного байт-кода перед его записью на диск. Это может быть критично для крупных проектов, где объем памяти, необходимый для хранения классов и ресурсов, значительно возрастает.
#Java #middle #Maven #LifeCicle
Maven — это мощный инструмент управления сборкой проектов, ядро которого составляет концепция жизненного цикла. Жизненный цикл Maven определяет последовательность фаз, через которые проходит проект во время сборки, обеспечивая предсказуемость и структурированность процесса.
Структура жизненного цикла Maven
Maven использует три основных жизненных цикла, каждый из которых представляет собой набор фаз, выполняемых последовательно для достижения определенной цели. Эти циклы — Clean, Default (Build) и Site — охватывают различные аспекты работы с проектом, от очистки до развертывания документации.
Clean Lifecycle
Жизненный цикл Clean отвечает за удаление артефактов, созданных в процессе предыдущих сборок, чтобы обеспечить чистую рабочую среду.
Он состоит из трех фаз:
pre-clean: Подготовка к очистке. На этой фазе выполняются предварительные действия, такие как завершение незавершенных процессов или освобождение ресурсов. Плагины редко привязаны к этой фазе, но она может использоваться для пользовательских задач, например, для проверки состояния проекта перед очисткой.
clean: Основная фаза очистки. Удаляет директорию target, содержащую скомпилированные классы, JAR-файлы, WAR-файлы и другие артефакты. По умолчанию к этой фазе привязан плагин maven-clean-plugin с целью clean.
post-clean: Завершающие действия после очистки. Эта фаза редко используется, но может быть полезна для выполнения дополнительных операций, таких как логирование или уведомления.
В памяти на этапе Clean происходит освобождение ресурсов, связанных с предыдущими сборками. Maven загружает конфигурацию проекта (POM-файл) в оперативную память, создает объектную модель проекта (POM model), которая хранит метаданные о проекте, зависимостях и плагинах. Во время выполнения clean Maven взаимодействует с файловой системой, удаляя указанные директории, что минимизирует использование памяти, так как не создаются новые артефакты.
Default (Build) Lifecycle
Default — наиболее важный жизненный цикл, охватывающий процесс сборки, тестирования и развертывания артефактов.
Он включает множество фаз, из которых наиболее часто используемые:
validate: Проверяет корректность структуры проекта и наличие всех необходимых ресурсов, таких как POM-файл и зависимости. Maven загружает и валидирует модель POM, проверяя синтаксис и доступность репозиториев.
compile: Компилирует исходный код проекта. По умолчанию используется maven-compiler-plugin, который преобразует Java-файлы в байт-код, сохраняя его в директории target/classes.
test: Выполняет модульные тесты с использованием плагинов, таких как maven-surefire-plugin. Тесты запускаются в изолированной среде, а результаты сохраняются в target/surefire-reports.
package: Создает артефакт (JAR, WAR, EAR и т.д.) на основе скомпилированного кода и ресурсов. Используется, например, maven-jar-plugin для создания JAR-файлов.
verify: Проверяет качество артефакта, выполняя интеграционные тесты или проверки, например, с помощью maven-failsafe-plugin.
install: Устанавливает артефакт в локальный репозиторий (~/.m2/repository), делая его доступным для других локальных проектов.
deploy: Разворачивает артефакт в удаленный репозиторий для общего использования. Используется maven-deploy-plugin.
Каждая фаза Default цикла добавляет новые данные в директорию target, что увеличивает объем используемой памяти. Например, во время компиляции Maven загружает в память исходные файлы, зависимости и настройки компилятора. Плагины, такие как maven-compiler-plugin, создают временные структуры данных для хранения промежуточного байт-кода перед его записью на диск. Это может быть критично для крупных проектов, где объем памяти, необходимый для хранения классов и ресурсов, значительно возрастает.
#Java #middle #Maven #LifeCicle
Site Lifecycle
Site цикл отвечает за генерацию и развертывание документации проекта.
Он включает две фазы:
site: Генерирует документацию, такую как Javadoc или отчеты о покрытии кода, используя плагины вроде maven-site-plugin. Результаты сохраняются в target/site.
site-deploy: Разворачивает сгенерированную документацию на сервер, например, с помощью maven-scm-publish-plugin.
На этапе Site Maven загружает в память шаблоны для генерации документации, а также данные о проекте, такие как зависимости и отчеты. Использование памяти зависит от объема документации и сложности отчетов, например, при генерации Javadoc для большого проекта.
Заказ выполнения фаз и их взаимосвязь
Фазы в каждом жизненном цикле выполняются строго последовательно, и выполнение одной фазы автоматически запускает все предыдущие фазы в рамках того же цикла. Например, вызов mvn install в Default цикле приведет к выполнению всех фаз от validate до install в следующем порядке: validate, compile, test, package, verify, install. Это обеспечивает целостность сборки, так как каждая фаза опирается на результаты предыдущих.
Между циклами нет автоматической связи. Например, выполнение mvn clean не запускает фазы Default цикла. Однако часто используется комбинация циклов, например, mvn clean install, где сначала выполняется очистка, а затем полный цикл сборки. Maven обрабатывает такие команды последовательно, освобождая память после завершения каждого цикла, если это возможно.
В памяти Maven поддерживает объектную модель проекта, которая обновляется на каждой фазе. Например, на фазе compile добавляются данные о скомпилированных классах, а на фазе test — результаты тестов. Если процесс сборки прерывается, Maven сохраняет промежуточные результаты на диске (в target), чтобы минимизировать потери при повторном запуске.
Bindings фаз к плагинам по умолчанию
Каждая фаза жизненного цикла связана с определенными целями (goals) плагинов, которые выполняют конкретные задачи. Maven использует механизм привязки (bindings), чтобы ассоциировать фазы с плагинами.
Например:
Фаза clean привязана к цели clean плагина maven-clean-plugin.
Фаза compile связана с целью compile плагина maven-compiler-plugin.
Фаза test использует цель test плагина maven-surefire-plugin.
Эти привязки определяются в так называемом "super POM" — базовом POM-файле, который наследуется всеми проектами Maven. Super POM задает стандартное поведение, но его можно переопределить в пользовательском POM-файле.
В памяти плагины загружаются как Java-объекты через классовый загрузчик Maven. Каждый плагин создает собственный контекст выполнения, который включает конфигурацию из POM-файла и параметры, переданные через командную строку. Это может приводить к значительному потреблению памяти, особенно если плагин выполняет сложные операции, такие как компиляция или анализ кода.
#Java #middle #Maven #LifeCicle
Site цикл отвечает за генерацию и развертывание документации проекта.
Он включает две фазы:
site: Генерирует документацию, такую как Javadoc или отчеты о покрытии кода, используя плагины вроде maven-site-plugin. Результаты сохраняются в target/site.
site-deploy: Разворачивает сгенерированную документацию на сервер, например, с помощью maven-scm-publish-plugin.
На этапе Site Maven загружает в память шаблоны для генерации документации, а также данные о проекте, такие как зависимости и отчеты. Использование памяти зависит от объема документации и сложности отчетов, например, при генерации Javadoc для большого проекта.
Заказ выполнения фаз и их взаимосвязь
Фазы в каждом жизненном цикле выполняются строго последовательно, и выполнение одной фазы автоматически запускает все предыдущие фазы в рамках того же цикла. Например, вызов mvn install в Default цикле приведет к выполнению всех фаз от validate до install в следующем порядке: validate, compile, test, package, verify, install. Это обеспечивает целостность сборки, так как каждая фаза опирается на результаты предыдущих.
Между циклами нет автоматической связи. Например, выполнение mvn clean не запускает фазы Default цикла. Однако часто используется комбинация циклов, например, mvn clean install, где сначала выполняется очистка, а затем полный цикл сборки. Maven обрабатывает такие команды последовательно, освобождая память после завершения каждого цикла, если это возможно.
В памяти Maven поддерживает объектную модель проекта, которая обновляется на каждой фазе. Например, на фазе compile добавляются данные о скомпилированных классах, а на фазе test — результаты тестов. Если процесс сборки прерывается, Maven сохраняет промежуточные результаты на диске (в target), чтобы минимизировать потери при повторном запуске.
Bindings фаз к плагинам по умолчанию
Каждая фаза жизненного цикла связана с определенными целями (goals) плагинов, которые выполняют конкретные задачи. Maven использует механизм привязки (bindings), чтобы ассоциировать фазы с плагинами.
Например:
Фаза clean привязана к цели clean плагина maven-clean-plugin.
Фаза compile связана с целью compile плагина maven-compiler-plugin.
Фаза test использует цель test плагина maven-surefire-plugin.
Эти привязки определяются в так называемом "super POM" — базовом POM-файле, который наследуется всеми проектами Maven. Super POM задает стандартное поведение, но его можно переопределить в пользовательском POM-файле.
В памяти плагины загружаются как Java-объекты через классовый загрузчик Maven. Каждый плагин создает собственный контекст выполнения, который включает конфигурацию из POM-файла и параметры, переданные через командную строку. Это может приводить к значительному потреблению памяти, особенно если плагин выполняет сложные операции, такие как компиляция или анализ кода.
#Java #middle #Maven #LifeCicle