← Назад к вопросам

Что использовал при сборке проектов: Mavel или Gradle

1.2 Junior🔥 121 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Maven vs Gradle: что использовал при сборке проектов

Введение

В своих проектах я работал с обоими инструментами сборки. Каждый имеет свои преимущества и недостатки. Выбор зависит от требований проекта и предпочтений команды.

Maven

Maven — классический инструмент для сборки Java проектов, основанный на конфигурации (XML).

Структура проекта

myapp/
├── pom.xml                 # Конфигурация (Project Object Model)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/
│   │   │       └── App.java
│   │   └── resources/
│   │       └── application.properties
│   └── test/
│       ├── java/
│       │   └── com/example/
│       │       └── AppTest.java
│       └── resources/
└── target/                 # Артефакты (JAR, WAR)

Конфигурация (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>myapp</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    
    <name>My Application</name>
    <description>Sample Java project</description>
    
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring.version>3.0.0</spring.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <!-- PostgreSQL -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.5.0</version>
        </dependency>
        
        <!-- Тестирование -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.version}</version>
            </plugin>
        </plugins>
    </build>
</project>

Команды Maven

# Очистить build директорию
mvn clean

# Скомпилировать
mvn compile

# Запустить тесты
mvn test

# Собрать JAR
mvn package

# Установить в локальный репозиторий
mvn install

# Все вместе
mvn clean install

# Запустить приложение
mvn spring-boot:run

# Linting
mvn checkstyle:check
mvn pmd:check

# Тесты + сборка
mvn clean test package

Жизненный цикл Maven

clean          validate    compile    test    package    install    deploy
  ↓              ↓            ↓        ↓          ↓          ↓         ↓
 очистка      проверка    компиляция тесты   упаковка   локальное удалённое
   build        pom          Java              JAR/WAR   хранилище хранилище

Преимущества Maven

Стандартизация

  • Все Maven проекты имеют одинаковую структуру
  • Новый разработчик быстро ориентируется

Огромное сообщество

  • Миллионы артефактов в Maven Central
  • Много плагинов и решений

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

Мой проект → Spring Boot → Spring Core → другие зависимости
Maven автоматически скачивает ВСЕ

IDE интеграция

  • IntelliJ IDEA, Eclipse отлично работают с Maven

Недостатки Maven

XML боль

<!-- Много XML для простого проекта -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.0.0</version>
</dependency>

Медлительность

  • Больше времени на сборку
  • Много вычислений для построения графа зависимостей

Жёсткая структура

  • Сложно настраивать нестандартные процессы
  • Много плагинов для каждой задачи

Зависимость ада

Когда несколько версий одной зависимости в графе
Maven работает, но результат может быть неожиданным

Gradle

Gradle — современный инструмент для сборки, основанный на Groovy/Kotlin DSL.

Структура проекта

myapp/
├── build.gradle            # Конфигурация (Groovy/Kotlin)
├── settings.gradle         # Многомодульные настройки
├── gradle/wrapper/         # Gradle Wrapper
├── src/
│   ├── main/
│   │   ├── java/
│   │   ├── kotlin/
│   │   └── resources/
│   └── test/
│       ├── java/
│       ├── kotlin/
│       └── resources/
└── build/                  # Артефакты

Конфигурация (build.gradle)

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.0'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // Spring Boot
    implementation 'org.springframework.boot:spring-boot-starter-web:3.0.0'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    
    // PostgreSQL
    runtimeOnly 'org.postgresql:postgresql:42.5.0'
    
    // Lombok
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    
    // Тестирование
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
    
    // Конфигурация тестов
    testLogging {
        events "passed", "skipped", "failed"
        exceptionFormat "full"
    }
}

// Кастомная задача
tasks.register('customTask') {
    doLast {
        println 'Custom build task'
    }
}

Конфигурация на Kotlin

import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
    java
    id("org.springframework.boot") version "3.0.0"
    id("io.spring.dependency-management") version "1.1.0"
}

group = "com.example"
version = "1.0.0"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    runtimeOnly("org.postgresql:postgresql")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

Команды Gradle

# Инициализировать Gradle Wrapper
gradle wrapper

# Очистить
./gradlew clean

# Скомпилировать
./gradlew build

# Запустить тесты
./gradlew test

# Запустить приложение
./gradlew bootRun

# Запустить конкретный тест
./gradlew test --tests UserServiceTest

# С логами
./gradlew build --info
gradle build --debug

# Dependency tree
./gradlew dependencies

# Список задач
./gradlew tasks

Gradle Wrapper

# Wrapper автоматически скачивает нужную версию Gradle
# Все разработчики используют одинаковую версию

# Первый запуск
./gradlew build  # Скачивает Gradle, если не установлен

# Следующий раз
./gradlew build  # Использует кэшированную версию

Преимущества Gradle

Читаемость

// Groovy DSL — понятнее XML
implementation 'org.springframework.boot:spring-boot-starter-web'

Скорость

  • Incremental builds (собирает только изменённое)
  • Параллельная компиляция
  • Gradle Daemon для горячего старта

Гибкость

// Кастомная логика в build скрипте
task customBuild {
    doLast {
        // Произвольный код на Groovy/Kotlin
    }
}

Лучший dependency management

dependencies {
    // Ясно видно версии конфликтов
    api 'org.springframework:spring-core:5.3.0'
    implementation 'org.springframework.boot:spring-boot-starter:3.0.0'
}

Современнее

  • Kotlin DSL поддерживает IDE suggestions
  • Лучше работает с многомодульными проектами

Недостатки Gradle

Кривая обучения

  • Groovy/Kotlin DSL сложнее XML
  • Документация иногда неполная

Медленнее при холодном старте

  • Первый запуск может быть медленным
  • Нужно использовать Gradle Daemon

Меньше сообщество

  • Фреймворки лучше поддерживают Maven
  • Меньше готовых решений

Сложнее DEBUG-ить

  • Когда что-то не работает, сложнее найти причину
  • Stack traces могут быть путанными

Что я использовал в реальных проектах

Maven

✓ Корпоративные проекты
✓ Legacy приложения
✓ Когда нужна максимальная совместимость
✓ Большие многомодульные системы (для стабильности)
✓ Консервативные компании

Gradle

✓ Современные стартапы
✓ Новые проекты
✓ Android разработка (Gradle — стандарт)
✓ Когда нужна скорость сборки
✓ Многомодульные микросервисы

Сравнительная таблица

КритерийMavenGradle
КонфигурацияXML (verbose)Groovy/Kotlin DSL
Скорость сборкиМедленнееБыстрее (incremental)
Кривая обученияПростаяСложная
IDE поддержкаОтличнаяХорошая
ГибкостьОграниченнаяВысокая
СообществоОгромноеРастущее
Многомодульные проектыХорошоЛучше
Dependency resolutionПорядокБолее умное
PerformanceODaemon ускорение
ДокументацияПолнаяМожет быть лучше

Мое мнение

Если мне нужно выбрать для нового проекта:

Выбираю Gradle, потому что:

  1. Скорость сборки критична для разработки
  2. Современные инструменты (Kotlin DSL)
  3. Gradle Daemon делает итеративную разработку быстрой
  4. Лучше работает с микросервисами

Но использую Maven, если:

  1. Проект legacy, все уже на Maven
  2. Команда незнакома с Gradle
  3. Нужна максимальная совместимость
  4. Корпоративные требования

Best Practices

Maven

# Используй maven-wrapper для одинаковой версии
mvn wrapper:wrapper -Dmaven.wrapper.maven=3.8.1

# BOM для управления версиями
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Gradle

// Используй Gradle Wrapper
./gradlew wrapper --gradle-version=8.0.2

// Версионирование в catalog
catalogs {
    libs {
        version('spring', '3.0.0')
        library('spring.boot', 'org.springframework.boot', 'spring-boot-starter-web').versionRef('spring')
    }
}

dependencies {
    implementation(libs.spring.boot)
}

Заключение

Оба инструмента рабочие. Maven — проверенный временем, Gradle — современный и быстрый. В идеале, должен быть комфортен с обоими.

На собеседовании часто спрашивают, почему я выбрал тот или иной инструмент — это показывает, что я думаю о целостности проекта, а не просто выполняю задачи.

Что использовал при сборке проектов: Mavel или Gradle | PrepBro