← Назад к вопросам
Что происходит на этапе компиляции в Maven
1.7 Middle🔥 171 комментариев
#Docker, Kubernetes и DevOps#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Этапы компиляции в Maven
Maven — это инструмент для управления проектами Java, который включает мощную систему компиляции кода. Процесс компиляции в Maven состоит из нескольких этапов, каждый из которых выполняет важную функцию.
1. Жизненный цикл Maven (Build Lifecycle)
Compile Lifecycle:
validate
↓
initialize
↓
generate-sources ← Генерация исходного кода
↓
process-sources ← Обработка исходного кода
↓
generate-resources ← Генерация ресурсов
↓
process-resources ← Копирование/обработка ресурсов
↓
compile ← КОМПИЛЯЦИЯ JAVA КОДА
↓
process-classes ← Постобработка скомпилированного кода
↓
generate-test-sources ← Генерация тестовых источников
↓
process-test-sources ← Обработка тестовых источников
↓
generate-test-resources
↓
process-test-resources
↓
test-compile ← Компиляция тестов
↓
process-test-classes
↓
test ← Запуск тестов
↓
package ← Упаковка (JAR/WAR/EAR)
↓
install ← Установка в локальный репозиторий
↓
deploy ← Развёртывание в удалённый репозиторий
2. Этап compile (основная компиляция)
// Maven выполняет следующее:
// 1. Сканирует исходные файлы
src/main/java/**/*.java
// 2. Находит все зависимости (dependencies)
// из pom.xml и загружает их в классpath
// 3. Вызывает Java компилятор (javac)
javac -d target/classes \
-classpath [dependencies] \
src/main/java/**/*.java
// 4. Генерирует .class файлы
target/classes/com/example/MyClass.class
3. Процесс обработки ресурсов (process-resources)
// Перед компиляцией Maven обрабатывает ресурсы
// Входящие ресурсы:
src/main/resources/
├── application.properties
├── application.yml
├── logback.xml
└── schema.sql
// Выходящие ресурсы (в целевую папку):
target/classes/
├── application.properties
├── application.yml
├── logback.xml
└── schema.sql
// Особенность: Maven может подставлять переменные
// ${project.version}, ${project.name} и т.д.
4. Фильтрация ресурсов (Resource Filtering)
<!-- pom.xml -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<!-- Включить фильтрацию свойств -->
</resource>
</resources>
</build>
# src/main/resources/app.properties (ПЕРЕД обработкой)
app.name=${project.name}
app.version=${project.version}
app.buildTime=${maven.build.timestamp}
# target/classes/app.properties (ПОСЛЕ обработки)
app.name=MyApp
app.version=1.0.0
app.buildTime=2026-03-23T12:00:00Z
5. Компилятор по умолчанию (Maven Compiler)
<!-- pom.xml -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source> <!-- Исходная Java версия -->
<target>17</target> <!-- Целевая Java версия -->
<encoding>UTF-8</encoding> <!-- Кодировка файлов -->
<debug>true</debug> <!-- Дебаг информация -->
<compilerArgs>
<arg>-parameters</arg> <!-- Сохранять имена параметров -->
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
6. Генерация исходных файлов (generate-sources)
<!-- Пример: автоматическая генерация кода из схемы БД -->
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<!-- Конфигурация для генерации JOOQ классов -->
</configuration>
</execution>
</executions>
</plugin>
// Сгенерированный код (example)
public class UsersRecord extends Record5<...> {
// Автоматически сгенерировано из схемы БД
public Field<Integer> ID;
public Field<String> NAME;
public Field<String> EMAIL;
// ...
}
7. Обработка аннотаций (annotation processing)
<!-- pom.xml -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
// Исходный код с аннотациями
@Data // Lombok аннотация
public class User {
private String name;
private int age;
}
// После обработки аннотаций компилятор генерирует:
public class User {
private String name;
private int age;
// Сгенерировано Lombok processor
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; }
// ... equals(), hashCode(), toString()
}
8. Определение зависимостей (dependency resolution)
<!-- pom.xml -->
<dependencies>
<!-- На этапе compile эти зависимости добавятся в classpath -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
<scope>compile</scope> <!-- По умолчанию -->
</dependency>
<!-- test зависимости не входят в classpath компиляции -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Scope в Maven:
scope="compile" → Включена при компиляции и запуске
scope="test" → Только при тестировании
scope="provided" → Предоставляется контейнером (servlet-api)
scope="runtime" → Требуется при запуске, но не при компиляции
scope="optional" → Опциональная зависимость
9. Порядок выполнения фаз
# При команде: mvn clean compile
# 1. Clean lifecycle (выполняется из-за clean)
mvn clean:
- Удаляет target/
# 2. Default lifecycle (выполняется до compile включительно)
mvn compile:
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources ← Копирование ресурсов
- compile ← КОМПИЛЯЦИЯ
# Результат:
# target/classes/com/example/
# ├── MyClass.class
# ├── MyApp.class
# └── ...
# target/classes/
# ├── application.properties
# ├── logback.xml
# └── ...
10. Обработка зависимостей (transitive dependencies)
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<!-- Spring-boot-starter-web включает:
- spring-webmvc
- spring-boot-starter-json
- spring-boot-starter-tomcat
- и многие другие...
-->
# Просмотр дерева зависимостей
mvn dependency:tree
# Вывод:
# org.example:myapp:jar:1.0.0
# └── org.springframework.boot:spring-boot-starter-web:jar:3.2.0:compile
# ├── org.springframework.boot:spring-boot-starter:jar:3.2.0:compile
# │ ├── org.springframework.boot:spring-boot:jar:3.2.0:compile
# │ ├── org.springframework.boot:spring-boot-autoconfigure:jar:3.2.0:compile
# │ └── org.springframework:spring-context:jar:6.1.0:compile
# ├── org.springframework.boot:spring-boot-starter-json:jar:3.2.0:compile
# └── org.springframework.boot:spring-boot-starter-tomcat:jar:3.2.0:compile
11. Классификация ошибок при компиляции
// Ошибка компиляции (не может быть запущена)
public class Syntax {
public void test( {
// Missing ) - синтаксическая ошибка
}
}
// ERROR: Syntax error, insert ")" to complete FormalParameterList
// Ошибка типов
public class TypeMismatch {
public void test() {
String s = 42; // int не совместим с String
}
}
// ERROR: incompatible types: int cannot be converted to String
// Ошибка символа (неизвестный класс)
public class UnknownSymbol {
public void test() {
NonExistentClass obj = new NonExistentClass();
}
}
// ERROR: cannot find symbol: class NonExistentClass
12. Оптимизация компиляции
<!-- Использование incremental compilation -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<!-- Параллельная компиляция (Java 9+) -->
<fork>true</fork>
<meminitial>512m</meminitial>
<maxmem>1024m</maxmem>
<compilerArgs>
<arg>-J-Xms512m</arg>
<arg>-J-Xmx1024m</arg>
</compilerArgs>
</configuration>
</plugin>
# Пересборка только изменённых файлов
mvn compile
# Полная пересборка
mvn clean compile
# Компиляция с параллельным выполнением
mvn -T 1C compile # T 1C = 1 thread per core
Best Practices
// 1. Всегда указывай версии Java
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
// 2. Включай обработку аннотаций
<configuration>
<annotationProcessorPaths>
<!-- Lombok и другие -->
</annotationProcessorPaths>
</configuration>
// 3. Использование BOM для управления версиями
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
// 4. Фильтруй ненужные зависимости
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
Итог: Этап compile в Maven — это комплексный процесс, который включает:
- Обработку ресурсов (filtering)
- Генерацию кода (из аннотаций, схем БД)
- Разрешение зависимостей (dependency resolution)
- Компиляцию Java кода с помощью javac
- Генерацию .class файлов в target/classes
Правильная конфигурация Maven compile обеспечивает корректную сборку, управление версиями зависимостей и оптимизацию времени компиляции.