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

В чем разница между Gradle и Maven?

1.0 Junior🔥 191 комментариев
#Основы Java

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

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

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

# Разница между Gradle и Maven

Основное различие

Maven:

  • XML конфигурация
  • Declarative подход (что делать)
  • Конвенция над конфигурацией
  • Медленнее, строгая структура

Gradle:

  • Groovy/Kotlin скрипты
  • Imperative подход (как делать)
  • Гибче, более программируемый
  • Быстрее, инкрементальные сборки

1. Конфигурация

Maven - XML

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <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>
        </plugins>
    </build>
</project>

Проблемы:

  • Много boilerplate
  • Сложно читать и редактировать
  • Сложная логика требует плагинов
  • Медленно парситься

Gradle - Groovy/Kotlin

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

compile.sourceCompatibility = 11
compile.targetCompatibility = 11

dependencies {
    testImplementation 'junit:junit:4.13.2'
}

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

  • Компактнее
  • Дополнительная логика через Groovy/Kotlin
  • Или ещё компактнее на Kotlin DSL:
plugins {
    java
}

group = "com.example"
version = "1.0-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

dependencies {
    testImplementation("junit:junit:4.13.2")
}

2. Конвенция структуры

Maven - Строгая конвенция

my-app/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/              (исходный код)
│   │   └── resources/         (ресурсы)
│   └── test/
│       ├── java/              (тесты)
│       └── resources/         (test ресурсы)
├── target/                    (скомпилированный код)

Преимущество: каждый Maven проект выглядит одинаково. Недостаток: негибко.

Gradle - Гибкая конвенция

То же по умолчанию, но можно переопределить:

sourceSets {
    main {
        java.srcDirs = ['src/main/java']
        resources.srcDirs = ['src/main/resources']
    }
    test {
        java.srcDirs = ['src/test/java']
        resources.srcDirs = ['src/test/resources']
    }
}

3. Производительность сборки

Maven

Всегда выполняет полную сборку (по умолчанию).

$ mvn clean install
[INFO] Building my-app 1.0-SNAPSHOT
[INFO] Building jar: target/my-app-1.0-SNAPSHOT.jar
[INFO] BUILD SUCCESS

Время: может быть 30-60 сек даже на простом проекте.

Gradle

Инкрементальные сборки (только то, что изменилось):

$ gradle build
Build successful
Build time: 2.3s

Время: 2-5 сек даже при большом проекте (если ничего не изменилось).

Преимущество: в 10-20 раз быстрее при многократных сборках.

4. Конвенция жизненного цикла

Maven - Фиксированные фазы

Жизненный цикл (lifecycle) определён:

  1. validate
  2. compile
  3. test
  4. package
  5. integration-test
  6. verify
  7. install
  8. deploy

Делаешь mvn install → выполняются все фазы до install:

mvn install
# Выполнит: validate → compile → test → package → install

Всегда одинаково, не гибко.

Gradle - Flexible tasks

Таски определяются динамически:

gradle build          # выполнит compile и test
gradle test           # только тесты
gradle build -x test  # build без тестов

Гибче, но нужно знать что делают таски.

5. Зависимости и конфликты

Maven - Явная иерархия

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>   <!-- явно указываешь версию -->
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.0</version>
    </dependency>
</dependencies>

При конфликте версий: используется ближайший в дереве зависимостей (nearest).

Gradle - Более гибко

dependencies {
    implementation 'log4j:log4j:1.2.17'
    implementation 'org.springframework:spring-core:5.3.0'
}

Можно резолвить конфликты:

configurations.all {
    resolutionStrategy {
        force 'log4j:log4j:1.2.17'  // Force version
    }
}

6. Плагины и расширяемость

Maven - Плагины в pom.xml

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Визуально запутанно и сложно.

Gradle - Плагины как код

plugins {
    id 'com.github.johnrengelman.shadow' version '7.1.0'
}

shadow {
    relocate 'com.google.common', 'shadow.com.google.common'
}

Или вообще кастомный плагин:

task customTask {
    doLast {
        println 'Custom logic!'
    }
}

7. Multi-module проекты

Maven

<!-- pom.xml в root -->
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>parent</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>module-a</module>
        <module>module-b</module>
        <module>module-c</module>
    </modules>
</project>

Паралелизм ограничен. По умолчанию последовательно:

mvn clean install
# module-a → module-b → module-c (последовательно)

# Можно параллелизировать
mvn -T 1C install  # 1 thread per core

Gradle

// settings.gradle
rootProject.name = 'my-app'
include 'module-a', 'module-b', 'module-c'

Паралелизм по умолчанию:

gradle build
# Параллельно выполняет модули (если нет зависимостей)

И гораздо быстрее благодаря incremental builds.

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

КритерийMavenGradle
КонфигурацияXML (verbose)Groovy/Kotlin (compact)
ГибкостьНизкаяВысокая
ПроизводительностьМедленнееБыстрее (10x+)
Кривая обученияСредняяКрутая
ЭкосистемаОгромнаяХорошая
Convention over configСтрогаяГибкая
Parallel buildsС трудомПо умолчанию
Incremental buildsНетДа
Инверсия управленияНизкаяВысокая

9. Когда использовать

Maven - выбирай если:

  • Легаси проект
  • Вся команда привыкла к Maven
  • Нужна минимальная конфигурация (convention-based)
  • Работаешь в корпоративной среде (эта инерция)

Gradle - выбирай если:

  • Новый проект
  • Нужна гибкость
  • Нужна производительность
  • Нужны custom build логики
  • Multi-module big project
  • Modern Android развитие (Gradle standard)

10. Практический пример: одна задача

Maven

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>com.example.Main</mainClass>
                <arguments>
                    <argument>arg1</argument>
                    <argument>arg2</argument>
                </arguments>
            </configuration>
        </plugin>
    </plugins>
</build>

Gradle

task run(type: JavaExec) {
    mainClass = 'com.example.Main'
    args = ['arg1', 'arg2']
    classpath = sourceSets.main.runtimeClasspath
}

Очень просто!

Резюме

Maven - консервативный, стабильный, хорош для простых проектов.

Gradle - современный, гибкий, мощный, лучше для сложных проектов.

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