Gradle 멀티모듈 구성

Seob·2025년 2월 24일
post-thumbnail

최근 프로젝트에서 멀티모듈 아키텍처를 구성하면서 Gradle을 Groovy 기반으로 설정하려고 했는데, 생각보다 다양한 오류들을 접하면서 Gradle의 구조와 설정 방식에 대한 이해가 부족하다는 것을 깨달았다. 이에 Gradle 멀티모듈 프로젝트를 구성하는 방법과 개념을 정리해보고자 한다.

1.1 루트 프로젝트와 서브모듈

  • root project: 최상위 디렉터리에 위치, build.gralde은 서브모듈에서 공통적인 설정을 정의하고 settings.gradle을 통해 서브모듈을 정의한다.
  • submodule: 개별적으로 빌드가 가능한 모듈이며, 각 모듈은 build.gradle 파일을 가진다.

2. Gradle 멀티모듈 설정하기

2.1 프로젝트 구조

아래와 같은 구조로 멀티모듈 프로젝트를 구성한다고 가정해보자.

random-ticket/
├── build.gradle  (루트 프로젝트 설정)
├── settings.gradle (서브모듈 등록)
├── api/  (API 모듈)
│   ├── build.gradle
├── independently-available/  (독립 실행 가능 모듈)
│   ├── build.gradle
├── system-domain/  (도메인 관련 모듈)
│   ├── build.gradle
├── in-system-available/  (시스템 내 사용 가능한 모듈)
│   ├── build.gradle

2.2 settings.gradle 설정

루트 프로젝트의 settings.gradle에서 서브모듈을 등록해야 한다.

rootProject.name = 'random-ticket'

include 'api'
include 'independently-available'
include 'system-domain'
include 'in-system-available'

2.3 Gradle의 주요 개념

2.3.1 Plugin과 Dependency Management

build.gradle에서는 플러그인과 의존성 관리를 설정할 수 있다. 예제에서 사용하는 플러그인과 그 역할은 다음과 같다.

plugins {
    id 'org.springframework.boot' version '3.4.3' apply false // 
    id 'io.spring.dependency-management' version '1.1.7'
}
  • org.springframework.boot: Spring Boot 애플리케이션을 빌드할 때 필요한 플러그인
  • io.spring.dependency-management: Spring Boot 프로젝트에서 의존성을 효율적으로 관리하기 위한 플러그인
  • apply false: 적용하지 않지만 하위 모듈에서 적용할 때 버전을 미리 지정해 놓음 (즉, 버전 통일 용도)

2.3.2 Repository와 mavenCentral()

Gradle에서 의존성을 가져올 때, 이를 어디에서 다운로드할 것인지를 지정하는 곳이 repositories이다.

  • mavenCentral(): Maven Central Repository에서 라이브러리를 가져옴, 대부분의 라이브러리가 등록되어있음, 가장 보편적

  • google(): Google에서 제공하는 Maven Repository(안드로이드 개발용)

  • jcenter(): 지금은 사용 X

  • ivy { url '...' }: 특정 사설(Private) 저장소를 추가할 때 사용

  • maven { url '...' }: 내부적으로 관리하는 저장소를 추가할 때 사용

repositories {
    mavenCentral()
}

2.3.3 Java Toolchain

Gradle은 프로젝트에 필요한 Java 버전을 명확하게 지정할 수 있도록 Java Toolchain을 지원한다.

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17) // JDK17
    }
}

위 코드는 프로젝트가 JDK 17을 사용하도록 강제하는 설정이다.

2.4 서브모듈 공통 설정 (subprojects)

루트 프로젝트에서는 모든 서브모듈에 공통적으로 적용할 설정을 subprojects 블록에서 정의할 수 있다.

subprojects {
    apply plugin: 'java'
    apply plugin: 'io.spring.dependency-management'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(17)
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    }

    tasks.withType(Test) {
        useJUnitPlatform()
    }
    
    //api 모듈만 bootJar 생성
    if (project.name != 'api') {
        bootJar {
            enabled = false
        }
        jar {
            enabled = true
        }
    }
}

이 설정을 통해 모든 서브모듈이 java 플러그인을 적용하고, Java 17을 사용하며, mavenCentral()에서 의존성을 가져오도록 한다.

bootJar 생성은 실행되는 api모듈으로 한정하고 나머지 모듈은 라이브러리로 사용되므로 jar로 생성

2.5 각 서브모듈에서 개별 설정 적용

각 서브모듈에서도 자체 build.gradle을 통해 필요한 의존성을 추가해야 합니다.

api 모듈 (api/build.gradle)

plugins {
id 'org.springframework.boot' // application 모듈은 spring boot 필요
}

dependencies {
//타 모듈 의존성 추가
implementation project(':system-domain')
implementation project(':in-system-available')

//의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

}

system-domain 모듈 (system-domain/build.gradle)

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
• 도메인 로직을 담당하는 모듈이므로 Web 관련 설정은 불필요

정리

1.	settings.gradle 에서 서브모듈을 명시적으로 선언해야 함.
2.	루트 build.gradle 에서 subprojects 블록을 활용하여 공통 설정을 적용.
3.	각 서브모듈의 build.gradle 에서 필요한 의존성을 개별적으로 관리.

이제 이 구조를 기반으로 개발을 진행하면 모듈 간의 의존성을 체계적으로 관리할 수 있다.

profile
백엔드 개발자 Seob입니다

0개의 댓글