Problem Statement
Explain Gradle build system including build.gradle syntax, dependency management, tasks, multi-project builds, and performance optimization techniques.
Explanation
Gradle uses Groovy or Kotlin DSL for build configuration. Build.gradle defines project structure:
```groovy
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
group = 'com.example'
version = '1.0.0'
sourceCompatibility = '11'
repositories {
mavenCentral()
maven {
url 'https://nexus.company.com/repository/maven-public/'
credentials {
username = System.getenv('NEXUS_USER')
password = System.getenv('NEXUS_PASSWORD')
}
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.postgresql:postgresql:42.3.1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.junit.jupiter:junit-jupiter'
}
tasks.named('test') {
useJUnitPlatform()
}
```
Dependency configurations: implementation (compile and runtime, not exposed to consumers), api (exposed to consumers in library projects), compileOnly (compile time only, like Maven provided), runtimeOnly (runtime only), testImplementation, testRuntimeOnly.
Dependency constraints and versions:
```groovy
dependencies {
implementation 'com.google.guava:guava:31.0-jre'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
// Constraint (doesn't add dependency, only sets version if included transitively)
constraints {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
}
```
Dependency resolution strategies:
```groovy
configurations.all {
resolutionStrategy {
// Force specific version
force 'com.google.guava:guava:31.0-jre'
// Fail on version conflict
failOnVersionConflict()
// Cache for 24 hours
cacheDynamicVersionsFor 24, 'hours'
}
}
```
Custom tasks:
```groovy
task hello {
doLast {
println 'Hello from Gradle!'
}
}
task copyDocs(type: Copy) {
from 'src/docs'
into 'build/docs'
}
task buildDockerImage(type: Exec) {
commandLine 'docker', 'build', '-t', "myapp:${version}", '.'
}
task dist(type: Zip) {
from 'build/libs'
archiveFileName = "myapp-${version}.zip"
}
```
Multi-project builds organize related projects:
```
root-project/
├── settings.gradle
├── build.gradle
├── app/
│ └── build.gradle
├── library/
│ └── build.gradle
└── common/
└── build.gradle
```
Settings.gradle:
```groovy
rootProject.name = 'my-application'
include 'app', 'library', 'common'
```
Root build.gradle:
```groovy
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.13.2'
}
}
```
App build.gradle:
```groovy
dependencies {
implementation project(':library')
implementation project(':common')
}
```
Performance optimization: Gradle daemon (enabled by default, reuses JVM across builds), build cache (caches task outputs):
```groovy
buildCache {
local {
enabled = true
}
remote(HttpBuildCache) {
url = 'https://cache.company.com/'
credentials {
username = System.getenv('BUILD_CACHE_USER')
password = System.getenv('BUILD_CACHE_PASSWORD')
}
push = true
}
}
```
Parallel execution:
```bash
./gradlew build --parallel
```
Configuration cache (faster configuration phase):
```bash
./gradlew build --configuration-cache
```
CI/CD integration:
```yaml
# GitHub Actions
- uses: gradle/gradle-build-action@v2
with:
arguments: build
cache-read-only: false
```
Publishing artifacts:
```groovy
plugins {
id 'maven-publish'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url = version.endsWith('SNAPSHOT') ?
'https://nexus.company.com/repository/maven-snapshots/' :
'https://nexus.company.com/repository/maven-releases/'
credentials {
username = System.getenv('NEXUS_USER')
password = System.getenv('NEXUS_PASSWORD')
}
}
}
}
```
Best practices: use Gradle wrapper, enable build cache, use parallel execution, leverage incremental compilation, cache dependencies in CI/CD, use configuration cache for large projects, profile builds (./gradlew build --scan), modularize large projects. Understanding Gradle enables efficient, flexible build automation.