최신 Gradle 프로젝트, dependencyResolutionManagement로 저장소를 중앙 관리하는 방법

소프트웨어 개발, 특히 안드로이드를 포함한 거대한 JVM(자바 가상 머신) 생태계에서 의존성 관리(Dependency Management)는 프로젝트의 안정성과 확장성을 결정짓는 가장 근본적인 초석입니다. 우리는 더 이상 필요한 라이브러리를 수동으로 다운로드하여 프로젝트에 포함시키지 않습니다. 대신 Gradle이나 Maven 같은 빌드 자동화 도구를 통해 원격 저장소(Remote Repository)에서 필요한 라이브러리를 선언적으로 가져와 사용합니다. 이 원격 저장소는 전 세계 개발자들이 만든 수많은 오픈소스 라이브러리를 한 곳에 모아 체계적으로 버전을 관리하고, 누구나 쉽게 사용할 수 있도록 하는 거대한 디지털 도서관과 같습니다. 불과 몇 년 전까지만 해도 이 도서관의 가장 큰 서고 중 하나는 단연 JCenter였습니다. 하지만 2021년, JCenter의 운영사 JFrog가 서비스 종료를 선언하면서 JVM 생태계, 특히 안드로이드 커뮤니티는 거대한 변화의 물결에 직면했습니다. 이 글은 단순히 `jcenter()`를 `mavenCentral()`로 바꾸라는 단편적인 지침을 넘어, 풀스택 개발자의 관점에서 JCenter의 흥망성쇠가 우리에게 남긴 교훈은 무엇인지, 그리고 최신 Gradle 프로젝트에서 왜 settings.gradledependencyResolutionManagement를 사용한 중앙 관리 방식이 새로운 표준으로 자리 잡았는지 그 기술적 배경과 실전 적용법까지 깊이 있게 파헤쳐 보겠습니다.

핵심 요약: 이 글을 다 읽고 나면, 여러분은 더 이상 `build.gradle` 파일에 흩어져 있는 `repositories` 블록을 보며 혼란스러워하지 않게 될 것입니다. 대신, 프로젝트의 모든 의존성 소스를 단 한 곳, `settings.gradle`에서 명확하고 안전하게 관리하는 방법을 완벽하게 이해하고 적용할 수 있게 됩니다.

JCenter의 시대는 끝났다: 왜 우리는 즉시 `jcenter()`를 제거해야 하는가

결론부터 단호하게 말씀드리겠습니다. 만약 여러분이 관리하는 프로젝트의 build.gradle 파일 어딘가에 `jcenter()`라는 코드가 남아있다면, 지금 당장 제거해야 합니다. 이는 권장 사항이 아닌, 프로젝트의 생존을 위한 필수 조치입니다. JCenter는 2022년 2월부로 서비스가 완전히 종료(Shutdown)되어 더 이상 어떠한 라이브러리 조회 및 다운로드도 보장하지 않습니다. JFrog가 남겨둔 일부 읽기 전용 캐시 서버가 간헐적으로 응답할 수도 있지만, 이는 언제 끊어질지 모르는 썩은 동아줄에 의지하는 것과 같습니다. 이 불안정한 상태는 예측 불가능한 빌드 실패의 직접적인 원인이 되며, 더 심각하게는 의존성 하이재킹(Dependency Hijacking)과 같은 잠재적인 보안 위협에 프로젝트를 그대로 노출시키는 결과를 초래할 수 있습니다. 따라서 모든 프로젝트에서 `jcenter()` 선언을 제거하고, JVM 생태계의 오랜 표준 저장소인 `mavenCentral()`을 중심으로 재편하는 것은 더 이상 미룰 수 없는 과제입니다.

과거의 기억을 되짚어보면, 안드로이드 스튜디오에서 새 프로젝트를 생성할 때마다 우리는 당연하게 다음과 같은 코드를 마주했습니다.


// 과거의 build.gradle (루트 프로젝트)
// 경고: 이 설정은 현재 유효하지 않으며, 심각한 빌드 오류를 유발할 수 있습니다.
allprojects {
    repositories {
        google()
        jcenter() // <-- 바로 이 코드가 모든 문제의 시작입니다.
    }
}

JCenter의 서비스 종료는 많은 개발자들에게 일시적인 혼란과 불편함을 주었지만, 장기적인 관점에서는 의존성 관리의 중요성을 다시 한번 상기시키고, 특정 기업의 플랫폼에 대한 과도한 의존에서 벗어나 더 개방적이고 표준화된 방식으로 전환하는 건강한 계기가 되었습니다. 이제 JCenter가 어떻게 안드로이드 생태계의 심장이 될 수 있었는지, 그리고 왜 역사의 뒤안길로 사라질 수밖에 없었는지, 그 대안인 MavenCentral은 어떤 철학을 가지고 있는지를 이해함으로써 우리는 더욱 견고하고 지속 가능한 프로젝트를 설계할 수 있는 통찰력을 얻게 될 것입니다.

Maven 저장소의 양대 산맥: JCenter와 MavenCentral 비교 분석

JCenter의 몰락을 이해하기 위해서는 그 경쟁자이자 JVM 생태계의 원조 격인 MavenCentral과의 관계를 먼저 알아야 합니다. 이 둘은 단순히 라이브러리를 저장하는 공간이라는 기능을 넘어, 서로 다른 철학과 정책으로 개발자들에게 다른 경험을 제공했습니다.

1. MavenCentral: 신뢰와 안정성의 대들보

MavenCentral은 Apache Maven 프로젝트의 공식 중앙 저장소로, Sonatype이라는 회사에서 운영하고 있습니다. 이는 JVM 생태계에서 가장 오래되고 권위 있는 저장소로, 사실상 공개 라이브러리의 '표준'과 같은 역할을 수행해왔습니다. MavenCentral의 핵심 철학은 '신뢰'와 '안정성'입니다. 이러한 철학은 다소 엄격하고 까다로운 라이브러리 배포 절차에 그대로 반영되어 있습니다.

  • 소유권 증명 (Group ID): 라이브러리를 배포하려면, 개발자는 자신이 통제할 수 있는 도메인(예: `github.com/my-account`)을 기반으로 한 고유한 Group ID(예: `io.github.my-account`)를 증명해야 했습니다. 이는 라이브러리의 출처를 명확히 하고 중복과 혼동을 방지합니다.
  • 상세한 메타데이터 (POM): 모든 라이브러리는 프로젝트의 정보, 라이선스, 의존성 관계, 개발자 정보 등을 상세히 기술한 POM(Project Object Model) 파일, 즉 pom.xml을 필수로 포함해야 합니다. 이는 라이브러리의 투명성을 높여줍니다.
  • GPG 서명 의무화: 배포되는 모든 파일(jar, aar 등)은 GPG(GNU Privacy Guard) 키로 디지털 서명되어야 합니다. 이 서명은 배포자가 누구인지 신원을 보증하고, 전송 과정에서 파일이 위변조되지 않았음을 보장하는 핵심적인 보안 장치입니다.
  • 소스 및 문서 제공: 라이브러리 사용자의 이해를 돕기 위해 소스 코드(`-sources.jar`)와 API 문서(`-javadoc.jar`)를 함께 배포하는 것이 사실상 의무화되어 있습니다.

이러한 절차들은 분명 라이브러리의 품질과 신뢰도를 비약적으로 높였지만, 개인 개발자나 소규모 오픈소스 프로젝트에게는 상당한 진입 장벽으로 느껴졌습니다. Sonatype의 JIRA 시스템을 통해 티켓을 생성하고 승인을 기다리는 과정은 많은 개발자들에게 복잡하고 불편한 경험을 안겨주었습니다.

2. JCenter의 등장: 편리함으로 생태계를 정복하다

MavenCentral의 높은 진입 장벽이라는 '틈새'를 정확히 파고든 것이 바로 JFrog사가 Bintray 플랫폼 위에서 운영한 JCenter였습니다. JCenter의 핵심 전략은 '개발자 친화적인 경험'과 '압도적인 편리함'이었습니다.

  • 간소화된 배포 절차: GPG 서명이 필수가 아니었고, 웹 UI를 통해 직관적으로 라이브러리를 업로드하고 관리할 수 있었습니다. 복잡한 설정 없이 몇 번의 클릭만으로 배포가 가능했습니다.
  • MavenCentral의 거대한 프록시(Proxy): 이것이 JCenter 성공의 가장 결정적인 요인이었습니다. JCenter는 자체 저장소이면서 동시에 MavenCentral의 모든 콘텐츠를 미러링하는 거대한 '상위 집합(Superset)'이었습니다. 즉, 개발자는 jcenter() 하나만 선언하면 JCenter 고유 라이브러리는 물론 MavenCentral의 모든 라이브러리까지 접근할 수 있었습니다. mavenCentral()을 굳이 함께 선언할 필요가 없었기 때문에, jcenter()는 사실상 유일한 필수 저장소로 여겨졌습니다.
  • 안드로이드 스튜디오의 기본 채택: 구글이 안드로이드 스튜디오의 기본 프로젝트 템플릿에 `jcenter()`를 포함시키면서, JCenter는 전 세계 수많은 안드로이드 개발자들의 기본값이 되었습니다. 이로 인해 JCenter는 명실상부 안드로이드 생태계의 표준 저장소로 군림하게 되었습니다.

비교 요약: JCenter vs MavenCentral

항목 MavenCentral (Sonatype) JCenter (JFrog/Bintray)
핵심 가치 신뢰성, 안정성, 보안 편의성, 개발자 경험, 속도
GPG 서명 필수 선택 사항 (권장)
배포 절차 까다롭고 복잡함 (JIRA 티켓 등) 간단하고 직관적임 (웹 UI 기반)
콘텐츠 범위 자체 배포된 라이브러리 자체 라이브러리 + MavenCentral 전체 미러링
주요 사용자 전통적인 Java/JVM 생태계 안드로이드 생태계의 사실상 표준

이러한 편리함 덕분에 JCenter는 수많은 라이브러리들의 보금자리가 되었고, 생태계는 폭발적으로 성장했습니다. 하지만 그 편리함의 이면에는 중앙 집중화된 단일 플랫폼에 대한 의존성이라는 거대한 리스크가 자리 잡고 있었습니다.

JCenter의 몰락과 그 이후: 개발 생태계에 남겨진 숙제

영원할 것 같았던 JCenter의 시대는 2021년 2월 3일, JFrog사의 한 건의 블로그 포스트로 갑작스럽게 막을 내렸습니다. JFrog는 자사의 핵심 비즈니스인 Artifactory와 같은 유료 솔루션에 집중하기 위해 Bintray 및 JCenter 서비스를 단계적으로 종료한다고 발표했습니다. 이는 생태계에 엄청난 충격파를 던졌습니다.

  • 2021년 3월 1일: 신규 라이브러리 및 버전 제출 중단.
  • 2021년 5월 1일: Bintray 서비스 전체가 읽기 전용(Read-Only)으로 전환. 기존 라이브러리 다운로드는 가능했지만, 업데이트는 불가능해졌습니다.
  • 2022년 2월 1일: JCenter 저장소 서비스 완전 종료. 이 시점 이후로 JCenter를 통한 라이브러리 다운로드는 공식적으로 불가능해졌습니다.

생태계에 미친 파장: '고아 라이브러리' 문제

JCenter의 종료는 개발자들에게 두 가지 큰 과제를 안겨주었습니다. 첫 번째는 모든 프로젝트에서 `jcenter()`를 `mavenCentral()`로 바꾸는 단순하지만 광범위한 작업이었습니다. 하지만 더 심각한 두 번째 문제는 바로 'JCenter-Only' 라이브러리들이었습니다.

JCenter의 편리함 때문에 그곳에만 라이브러리를 배포했던 수많은 개인 개발자 프로젝트나, 더 이상 활발히 관리되지 않는 오래된 오픈소스 프로젝트들이 문제였습니다. JCenter가 사라지면서 이 라이브러리들은 더 이상 빌드 시스템을 통해 자동으로 접근할 수 없는 '고아 라이브러리(Orphaned Libraries)'가 되어버렸습니다. 개발자들은 당장 빌드가 깨지는 상황에 직면했고, 다음과 같은 해결책을 찾아야만 했습니다.

  1. 대체 라이브러리 탐색: 가장 이상적인 방법입니다. 유사한 기능을 제공하면서 MavenCentral을 통해 활발하게 유지보수되는 다른 라이브러리를 찾아 마이그레이션하는 것입니다.
  2. 소스 코드 직접 빌드: 대체재가 없는 경우, 해당 라이브러리의 GitHub 소스 코드를 직접 클론하여 로컬에서 빌드한 후, `.jar` 또는 `.aar` 파일을 프로젝트에 수동으로 포함시키는 방법입니다. 이는 임시방편일 뿐 장기적인 해결책은 아닙니다.
  3. 다른 저장소로의 이전 확인: 라이브러리 관리자가 JitPack과 같은 다른 대안 저장소로 이전했을 가능성을 확인하는 것입니다.

이러한 혼란은 특정 기업의 서비스에 생태계 전체가 과도하게 의존하는 것이 얼마나 위험한지를 보여주는 뼈아픈 교훈이 되었습니다. 이는 우리가 지금부터 논의할 '저장소 중앙 관리'의 중요성을 더욱 부각시키는 계기가 되었습니다.

새로운 표준의 도래: `settings.gradle`과 `dependencyResolutionManagement`

JCenter 사태를 겪으며 Gradle 개발팀과 커뮤니티는 의존성 관리 방식의 근본적인 개선 필요성을 절감했습니다. 기존 방식은 각 모듈의 `build.gradle` 파일에 `repositories` 블록을 개별적으로 선언하는 것이었습니다. 이는 다음과 같은 문제점을 안고 있었습니다.

  • 분산된 설정: 프로젝트가 커지고 모듈이 많아지면, 어떤 모듈이 어떤 저장소를 사용하는지 한눈에 파악하기 어렵습니다. 저장소 추가, 삭제, 순서 변경 등의 작업이 매우 번거롭고 실수를 유발하기 쉽습니다.
  • 일관성 부족: A 모듈은 `mavenCentral()`을, B 모듈은 `jitpack.io`를 사용하는 등 일관성 없는 설정이 가능하여 빌드 동작을 예측하기 어렵게 만듭니다.
  • 보안 취약점: 특정 모듈의 `build.gradle`에 개발자가 임의로 신뢰할 수 없는 HTTP 저장소나 개인 저장소를 추가하기 쉽습니다. 이는 악의적인 라이브러리가 주입될 수 있는 통로가 될 수 있습니다.

이러한 문제들을 해결하기 위해 Gradle 7.x 버전부터 `settings.gradle` 파일 내에 `dependencyResolutionManagement` 블록을 사용하여 프로젝트 전체의 저장소를 중앙에서 관리하는 방식이 강력하게 권장되기 시작했습니다. 이것이 바로 현대적인 Gradle 프로젝트의 새로운 표준입니다.

왜 `dependencyResolutionManagement`인가? 그 장점들

이 새로운 방식은 단순히 코드를 한 곳으로 옮기는 것 이상의 의미를 가집니다.

  • 중앙 관리 (Single Source of Truth): 프로젝트의 모든 모듈이 사용할 저장소 목록을 단 한 곳, `settings.gradle` 파일에서 정의합니다. 이것이 '진실의 유일한 원천' 역할을 하여 설정이 명확해지고 유지보수가 극적으로 쉬워집니다.
  • 강제성을 통한 보안 강화: repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 설정을 통해, 각 모듈의 `build.gradle`에 `repositories` 블록을 선언하는 행위 자체를 금지하고 빌드를 실패시킬 수 있습니다. 이는 중앙에서 허가하지 않은 저장소가 추가되는 것을 원천적으로 차단하는 강력한 보안 장치입니다.
  • 빌드 성능 향상: Gradle은 의존성을 해결하기 위해 선언된 모든 저장소를 순서대로 확인합니다. 저장소 목록이 프로젝트 전체에 걸쳐 일관되게 유지되면, Gradle의 의존성 분석 및 캐싱 메커니즘이 더 효율적으로 작동하여 잠재적으로 빌드 성능을 향상시킬 수 있습니다.

실전 적용: `settings.gradle(.kts)` 설정 예시

이제 여러분의 프로젝트에 새로운 표준을 적용해 봅시다. 프로젝트 최상위 디렉토리에 있는 `settings.gradle`(Groovy DSL) 또는 `settings.gradle.kts`(Kotlin DSL) 파일을 열고 다음과 같이 구성하는 것이 현재 가장 권장되는 방식입니다.

Groovy DSL (`settings.gradle`)


// settings.gradle - 현대적인 Gradle 프로젝트의 표준 설정
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    // 이 설정이 핵심: 각 build.gradle에 repositories가 있으면 빌드를 실패시킴
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        // 필요에 따라 신뢰할 수 있는 다른 저장소 추가
        // 예: maven { url 'https://jitpack.io' }
    }
}
rootProject.name = "MyAwesomeApp"
include ':app'
include ':core'
// ... 다른 모듈들

Kotlin DSL (`settings.gradle.kts`)


// settings.gradle.kts - 현대적인 Gradle 프로젝트의 표준 설정 (Kotlin DSL)
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    // 이 설정이 핵심: 각 build.gradle에 repositories가 있으면 빌드를 실패시킴
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        // 필요에 따라 신뢰할 수 있는 다른 저장소 추가
        // 예: maven { url = uri("https://jitpack.io") }
    }
}
rootProject.name = "MyAwesomeApp"
include(":app")
include(":core")
// ... 다른 모듈들

위 설정의 각 블록을 심도 있게 분석해 보겠습니다.

  • pluginManagement: 이 블록은 Gradle 플러그인(예: Android Gradle Plugin, Kotlin Gradle Plugin 등) 자체를 어디서 가져올지 정의합니다. 라이브러리 의존성과는 별개입니다. 일반적으로 구글 플러그인을 위한 google(), 대부분의 범용 플러그인을 위한 mavenCentral(), 그리고 Gradle이 공식적으로 운영하는 gradlePluginPortal()을 포함하는 것이 표준입니다.
  • dependencyResolutionManagement: 이 블록이 바로 프로젝트의 라이브러리 의존성(implementation, api 등으로 추가하는 것들)을 가져올 저장소를 중앙에서 관리하는 곳입니다.
    • repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS): 이 한 줄이 거버넌스의 핵심입니다. 이 설정을 추가하면, 만약 어떤 개발자가 실수로든 의도적으로든 하위 모듈의 build.gradle 파일 내부에 repositories { ... } 블록을 추가하면 Gradle은 즉시 빌드를 중단시키고 오류를 발생시킵니다. 이를 통해 모든 저장소 관련 설정 변경은 반드시 이 `settings.gradle` 파일을 통해서만 이루어지도록 강제할 수 있습니다.
    • repositories { ... }: 여기에 선언된 저장소 목록이 프로젝트의 모든 모듈에 적용됩니다. JCenter가 사라진 지금, google()mavenCentral()이 사실상의 표준 조합입니다. Gradle은 의존성을 찾을 때 여기에 선언된 순서대로 저장소를 검색합니다.

이렇게 `settings.gradle` 파일을 설정하고 나면, 루트 프로젝트나 각 하위 모듈의 `build.gradle` 파일에서는 더 이상 repositories 블록을 찾아볼 수 없게 됩니다. 코드는 훨씬 간결하고 명확해지며, 프로젝트의 의존성 소스는 완벽하게 통제됩니다.

마이그레이션 실전 가이드: JCenter의 흔적을 완전히 지우는 방법

이제 이론을 실전에 적용할 시간입니다. 오래된 프로젝트에서 JCenter의 흔적을 지우고 현대적인 방식으로 전환하는 구체적인 단계를 안내합니다.

1단계: 모든 `build.gradle` 파일에서 `repositories` 블록 제거

가장 먼저 할 일은 프로젝트 내의 모든 build.gradlebuild.gradle.kts 파일(루트 프로젝트 및 모든 하위 모듈 포함)을 열어 `repositories` 블록과 그 안의 `jcenter()` 선언을 모두 삭제하는 것입니다. 기존의 buildscript { repositories { ... } }allprojects { repositories { ... } } 블록도 예외 없이 제거합니다.


// build.gradle (루트 프로젝트) - 수정 전
// 이 블록 전체를 삭제합니다!
buildscript {
    repositories {
        google()
        jcenter() // 삭제 대상
    }
    // ...
}

// 이 블록 전체를 삭제합니다!
allprojects {
    repositories {
        google()
        jcenter() // 삭제 대상
    }
}

모듈 수준의 `build.gradle` 파일에 개별적으로 선언된 `repositories` 블록이 있다면 그것 역시 모두 삭제해야 합니다.

2단계: `settings.gradle`에 중앙 저장소 설정 추가

다음으로, 프로젝트 최상위의 settings.gradle` 또는 `settings.gradle.kts` 파일을 열어 바로 위 섹션에서 설명한 `pluginManagement`와 `dependencyResolutionManagement` 블록을 추가하거나 수정합니다. 이것으로 저장소 설정은 완료됩니다.

3단계: 빌드 및 오류 해결

이제 Android Studio에서 "Sync Project with Gradle Files"를 실행하거나 터미널에서 ./gradlew build 명령을 실행하여 프로젝트를 다시 빌드합니다. 이때, 일부 의존성을 찾지 못한다는 빌드 오류가 발생할 수 있습니다.


FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Could not resolve all files for configuration ':app:debugCompileClasspath'.
   > Could not find com.some.legacy:jcenter-only-library:1.2.3.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/
       - https://repo.maven.apache.org/maven2/
     Required by:
         project :app

이 오류는 해당 라이브러리(`com.some.legacy:jcenter-only-library:1.2.3`)가 'JCenter-Only' 라이브러리였음을 명백히 보여줍니다. 이 문제를 해결하기 위한 체계적인 접근법은 다음과 같습니다.

  1. 최신 버전 확인 및 마이그레이션: 가장 먼저 해당 라이브러리의 GitHub 저장소나 공식 문서를 방문하세요. 대부분의 활성화된 프로젝트들은 JCenter 종료 이후 MavenCentral로 배포처를 옮겼습니다. 단순히 라이브러리 버전을 최신으로 업데이트하는 것만으로 문제가 해결될 수 있습니다.
  2. 공식 대체 라이브러리 탐색: 라이브러리 관리자가 프로젝트를 아카이빙하면서 공식적인 대체재(예: "이 라이브러리는 더 이상 사용되지 않으며, 대신 XXX 라이브러리를 사용하세요")를 안내하는 경우가 많습니다. 이는 가장 안전하고 권장되는 해결책입니다.
  3. 커뮤니티 대체 라이브러리 탐색: 공식 대체재가 없다면, Android Arsenal이나 GitHub 검색을 통해 유사한 기능을 제공하는 다른 활성화된 라이브러리를 찾아야 합니다. 단순히 기능뿐만 아니라, 최근까지 커밋이 있는지, 이슈는 잘 관리되는지 등 프로젝트의 건강 상태를 반드시 확인해야 합니다.
  4. JitPack 또는 다른 저장소 확인: 일부 라이브러리는 MavenCentral의 복잡한 절차 대신 간편한 JitPack으로 이전했을 수 있습니다. 라이브러리 문서를 확인하여 JitPack을 통해 배포되는지 확인하고, 만약 그렇다면 `settings.gradle`의 `repositories` 블록에 `maven { url 'https://jitpack.io' }`를 추가해야 합니다.
경고: 문제가 해결되지 않는다고 해서 인터넷 검색으로 찾은 불분명한 `maven { url '...' }` 주소를 `settings.gradle`에 무분별하게 추가해서는 안 됩니다. 이는 프로젝트의 보안을 심각하게 위협하는 행위입니다. 반드시 공식 문서나 신뢰할 수 있는 출처를 통해 확인된 저장소만 추가해야 합니다.

이 과정을 통해 프로젝트의 모든 의존성을 JCenter로부터 완전히 독립시키고, 안정적이며 신뢰할 수 있는 소스에서만 가져오도록 재구성해야 합니다. 이것이 바로 장기적으로 안정적인 빌드 환경을 확보하는 유일한 길입니다.

MavenCentral 너머의 세계: `google()`, `JitPack` 그리고 사설 저장소

우리의 주 저장소는 이제 `mavenCentral()`이 되었지만, 실제 개발 환경은 여러 저장소가 목적에 따라 공존하는 형태입니다. `dependencyResolutionManagement`를 통해 우리는 이들을 체계적으로 관리할 수 있습니다.

저장소 단축 표현 주요 콘텐츠 용도 및 특징
Google Maven Repository google() AndroidX, Material Components, Google Play Services, Firebase, Hilt 등 안드로이드 개발의 필수 저장소. 구글이 직접 제공하는 모든 공식 라이브러리를 호스팅합니다. 일반적으로 `mavenCentral()`보다 먼저 선언하여 우선순위를 높입니다.
Maven Central mavenCentral() 전 세계 JVM 생태계의 거의 모든 주요 오픈소스 라이브러리 JVM 생태계의 표준 중앙 저장소. 가장 방대하고 신뢰할 수 있는 라이브러리들을 포함합니다. 안드로이드 개발에서도 `google()` 다음으로 필수적입니다.
JitPack maven { url 'https://jitpack.io' } GitHub, GitLab, Bitbucket 등의 Git 저장소 Git 저장소를 즉석에서 빌드하여 라이브러리로 제공합니다. 포크된 프로젝트 사용, 최신 커밋 테스트, 간단한 라이브러리 공유에 매우 유용하지만, 최초 빌드 속도가 느리고 안정성은 떨어질 수 있습니다.
사설(Private) 저장소 maven { url '...' } 사내 라이브러리, 외부 라이브러리 캐시 기업 환경에서 보안 및 저작권 관리를 위해 사용됩니다. JFrog Artifactory, Sonatype Nexus 등이 대표적이며, 내부망에서만 접근 가능하도록 구성하는 경우가 많습니다.

이처럼 목적에 따라 다양한 저장소를 활용하되, 그 모든 관리는 `settings.gradle`이라는 단일 제어 지점을 통해 이루어지도록 하는 것이 현대적인 Gradle 관리의 핵심 철학입니다.

결론: 의존성 관리는 프로젝트 아키텍처의 시작이다

JCenter의 화려한 등과와 갑작스러운 퇴장은 우리에게 많은 것을 시사합니다. 특정 플랫폼의 편리함에 과도하게 의존하는 것의 위험성, 그리고 개방적이고 표준화된 생태계의 중요성을 다시 한번 깨닫게 된 계기였습니다. 이제 우리는 JCenter가 남긴 교훈을 바탕으로 더 성숙하고 안정적인 개발 환경을 구축해야 할 책임이 있습니다.

이 글에서 제시한 새로운 표준을 다시 한번 요약하며 마무리하겠습니다.

  1. `jcenter()`는 역사의 유물입니다. 지금 즉시 모든 프로젝트에서 그 흔적을 완전히 제거해야 합니다.
  2. 현대적인 Gradle 프로젝트의 표준 저장소 구성은 `google()`과 `mavenCentral()`의 조합입니다. 이 둘은 안드로이드 개발에 있어 선택이 아닌 필수입니다.
  3. 모든 저장소 설정은 settings.gradle(.kts)dependencyResolutionManagement 블록을 통해 중앙에서 관리해야 합니다. repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 설정으로 이를 강제하여 프로젝트의 일관성, 보안, 유지보수성을 극대화하세요.
  4. '고아 라이브러리' 문제는 회피하지 말고 적극적으로 해결해야 합니다. 최신 버전으로 업데이트하거나, 더 건강한 대체 라이브러리로 마이그레이션하는 것은 프로젝트의 수명을 연장하는 필수적인 과정입니다.
의존성 저장소를 올바르게 구성하는 것은 단순히 빌드를 성공시키는 기술적인 작업을 넘어, 우리 소프트웨어의 안정성과 보안, 미래 확장성을 담보하는 가장 첫 번째 아키텍처 설계 과정입니다.

JCenter가 떠난 자리에 우리는 `mavenCentral()`이라는 견고한 반석을 되찾았고, `dependencyResolutionManagement`라는 강력한 도구를 얻었습니다. 이제 이 도구들을 활용하여 더욱 예측 가능하고, 안전하며, 효율적인 개발을 이어나가야 할 때입니다.

Post a Comment