Gradle
Gradle
Gradle 은 JVM 생태계의 빌드 도구 가운데 가장 널리 쓰이는 축. 이 글은 Gradle 의 출자 · 동작 · Maven 과의 차이.
1. Gradle 에 대한 이야기
Hans Dockter 가 2007 년 시작해 2012 년 6월에 1.0 정식 릴리스를 낸 빌드 도구. 회사 Gradleware 는 이후 Gradle Inc. 로 이름을 바꿈. 라이선스는 Apache 2.0.
초기에는 Groovy DSL 로 빌드 스크립트 (build.gradle) 를. Kotlin DSL (build.gradle.kts) 은 1.0 이 2018 년 11월에 들어갔고, 이후 Android Studio 신규 프로젝트의 기본 DSL 이 Kotlin 으로 바뀌며 채택이 빠르게 늘었습니다.
Android 빌드 도구가 Gradle 을 채택 (2013 년 Android Studio 공개) 하면서 Java / Kotlin 진영 전반의 표준격이 됐습니다.
2. 핵심 모델
Gradle 의 빌드는 태스크의 방향성 비순환 그래프 (DAG). build 태스크는 compileJava 를 의존하고, 그것은 processResources 를 의존하는 식. Gradle 이 의존을 풀어 올바른 순서로 실행.
태스크는 입력 (input) 과 출력 (output) 을 선언할 수 있고, 입력 해시가 같으면 결과를 캐시에서 가져옴. 이 메커니즘이 빌드 시간을 줄이는 1차 수단.
3. Wrapper
저장소에 gradlew (Unix) 와 gradlew.bat (Windows) 그리고 gradle/wrapper/gradle-wrapper.properties 를 커밋. 이 파일이 사용할 Gradle 버전을 박아 두고, 처음 실행 시 해당 버전을 다운로드해 사용. 시스템에 Gradle 이 설치돼 있지 않아도 동일한 빌드 가능.
# Windows
./gradlew.bat build
# macOS · Linux
./gradlew build
4. Daemon
Gradle 은 백그라운드 데몬 프로세스를 띄워 JVM 시작 비용과 캐시를 재사용. 기본 활성화. 처음 실행은 느려도 두 번째부터 짧음.
5. Build Cache · Configuration Cache
- Build cache — 태스크 출력을 키-값으로 저장. 로컬 캐시는 기본 활성화, 원격 캐시 (서버) 는 옵션.
- Configuration cache — 빌드 설정 단계의 결과를 저장해 다음 호출 시 재구성을 건너뜀. 일정 안정화 후 9.x 시점에 점차 기본에 가까운 위치로 이동.
6. 멀티프로젝트
루트의 settings.gradle(.kts) 가 포함할 모듈을 선언:
// settings.gradle.kts
rootProject.name = "myapp"
include("api", "common", "worker")
각 모듈에 build.gradle.kts 를 두고, 내부 의존성은 implementation(project(":common")) 로 적습니다.
7. 다른 길
| 도구 | 첫 릴리스 | 위치 |
|---|---|---|
| Apache Ant | 2000 | XML 기반. 빌드 단계를 직접 적음. 의존성 관리 별도 (Ivy). |
| Apache Maven | 2004 | XML (pom.xml). 컨벤션 우선 · 의존성 관리 내장. 엔터프라이즈에서 여전히 다수. |
| Gradle | 2012 (1.0) | DSL 기반. 점진 빌드 · 캐시 · 데몬으로 빌드 시간 단축에 강점. |
| Bazel | 2015 (OSS) | Google Blaze 의 OSS. 결정적 빌드 · 원격 실행. JVM 외에도 광범위. |
Maven 과의 차이:
- 표현 — XML 트리 vs DSL (코드). DSL 은 조건 / 반복이 자유로운 반면 가독성은 XML 이 평이하다는 평.
- 캐시 · 점진 빌드 — Gradle 은 입출력 기반 캐시가 1급. Maven 은 멀티모듈 빌드에서 변경 미발생 모듈을 자동으로 건너뛰는 능력이 약함.
- 데몬 — Gradle 만 기본 데몬. JVM 시작 비용 축소.
- 학습 곡선 — Maven 은 컨벤션이 강하고 정형적, Gradle 은 자유도가 높은 만큼 잘못 짜면 디버깅이 어려워짐.
8. 자주 쓰는 모양
기본 명령:
./gradlew tasks # 전체 태스크 목록
./gradlew :api:build # 특정 모듈만
./gradlew test --tests "com.example.UserServiceTest"
./gradlew clean build --no-daemon
./gradlew dependencies # 의존성 트리
./gradlew --refresh-dependencies # 캐시 무시 재해소
build.gradle.kts (Spring Boot 축약):
plugins {
java
id("org.springframework.boot") version "3.3.0"
id("io.spring.dependency-management") version "1.1.6"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }
repositories { mavenCentral() }
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test { useJUnitPlatform() }
gradle.properties 에 자주 적는 옵션:
org.gradle.jvmargs=-Xmx2g
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
9. 자주 걸리는 자리
호환 매트릭스 — Gradle 버전과 플러그인 버전, JDK 버전 사이의 호환이 깐깐. 공식 호환표를 빌드 깨짐 시 먼저 확인.
Wrapper 일부만 커밋 — 다른 머신에서 실행되지 않음. gradlew · gradlew.bat · gradle/wrapper/* 네 파일 모두를 함께 커밋.
명령형 코드 vs configuration cache — build.gradle(.kts) 에 명령형 코드를 많이 넣으면 configuration cache 와 충돌. 공식 문서가 권장하는 lazy API (tasks.register · Provider) 를 따름.
데몬 OOM — org.gradle.jvmargs 로 적정 힙을 명시하거나, CI 에서는 --no-daemon 으로 끄고 돌리는 패턴.
Groovy DSL · Kotlin DSL 혼재 — 한 모듈은 Groovy, 다른 모듈은 Kotlin 으로 섞으면 코드 공유가 어려움. 한 저장소에서는 한쪽으로 통일.
하고픈 말
Gradle 의 진가는 점진 빌드 + 빌드 캐시 + 데몬 셋의 결합. 큰 멀티모듈에서 Maven 보다 빌드 시간이 크게 짧아지는 자리. Wrapper 의 4 파일을 모두 커밋하면 머신마다 같은 빌드. Configuration cache 의 lazy API 를 따르는 편이 장기적으로 안전.
Next
- editor-setup
- linting-formatting
Gradle 공식 문서 · Gradle GitHub · Gradle Kotlin DSL Primer · Compatibility Matrix · Apache Maven 공식 문서 · Gradle Build Cache 가이드 · Gradle 블로그 를 참고합니다.