안녕하세요! 오늘은 자바 개발자, 특히 스프링 부트(Spring Boot)나 그레이들(Gradle) 환경에서 프로젝트를 빌드할 때 우리를 당황하게 만드는 대표적인 오류 중 하나인 "Cannot choose between the following variants" 해결 방법에 대해 심도 있게 알아보겠습니다.
이 오류는 보통 의존성 라이브러리 간의 충돌이나, 빌드 시스템이 특정 라이브러리의 여러 버전/설정 중 어떤 것을 사용해야 할지 결정하지 못할 때 발생합니다. 전문가의 시선에서 이 문제를 해부하고, 가장 깔끔하게 해결하는 가이드를 제시해 드리겠습니다.

1. "Cannot choose between the following variants" 오류의 본질적 원인
이 에러 메시지는 직역하면 "다음 변체(Variants)들 중 하나를 선택할 수 없습니다"라는 뜻입니다. Gradle이나 Maven 같은 빌드 도구가 라이브러리를 가져오려고 할 때, 검색된 라이브러리 목록에 동일하거나 유사한 속성을 가진 선택지가 너무 많아 우선순위를 정하지 못하는 상황을 의미합니다.
주로 다음과 같은 상황에서 빈번하게 발생합니다.
- 의존성 충돌 (Dependency Conflict): 동일한 라이브러리가 서로 다른 경로를 통해 중복으로 유입될 때
- 속성 매칭 실패 (Attribute Mismatch): 라이브러리가 제공하는 기능(예: Runtime, API)과 프로젝트가 요구하는 설정이 모호하게 겹칠 때
- 버전 업그레이드 여파: 라이브러리 내부 구조가 변경되면서 이전 설정과 호환되지 않는 새 'Variant'가 추가되었을 때
특히 최근 Gradle 6.x 버전 이후부터 'Variant-aware dependency management' 기능이 강화되면서, 과거에는 단순히 버전 충돌로 끝날 문제가 이처럼 구체적인 선택 오류로 나타나는 경우가 많아졌습니다.
2. 단계별 해결 프로세스: 가용 옵션 분석
오류를 해결하기 위해서는 먼저 어떤 라이브러리들이 충돌하고 있는지 정확히 파악해야 합니다. 아래의 단계를 차근차근 따라와 주세요.
Step 1. 의존성 리포트 확인하기
가장 먼저 해야 할 일은 터미널을 열고 다음 명령어를 입력하여 전체 의존성 트리를 확인하는 것입니다.
./gradlew dependencies
출력 내용 중에서 FAILED 표시가 된 부분을 찾거나, 문제가 된 라이브러리 이름을 검색해 보세요. 어떤 라이브러리가 중복으로 호출되고 있는지 한눈에 알 수 있습니다.
Step 2. 'Exclude'를 이용한 중복 제거
문제가 되는 특정 라이브러리가 다른 라이브러리에 의해 강제로 끌려 들어오고 있다면, exclude 구문을 사용하여 이를 제외시켜야 합니다.
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j'
}
}
Step 3. 특정 버전 강제하기 (Enforced Platform)
빌드 도구가 선택 장애를 겪고 있다면 개발자가 직접 '이 버전을 사용해!'라고 명시해 주는 것이 좋습니다. Gradle의 constraints 기능을 사용하면 우아하게 해결할 수 있습니다.
dependencies {
constraints {
implementation('com.google.guava:guava:30.1-jre') {
because 'previous versions had security vulnerabilities and caused variant conflicts'
}
}
}
3. 환경별 주요 해결 사례 (Spring Boot & Querydsl)
이 오류가 가장 많이 발생하는 대표적인 사례 두 가지를 살펴보겠습니다.
사례 A: Querydsl 설정 시 'jakarta' vs 'javax' 충돌
자바 진영이 javax에서 jakarta 패키지로 전환되면서 발생하는 문제입니다. querydsl-jpa 라이브러리를 가져올 때 어떤 Classifier를 사용할지 명시하지 않으면 이 에러가 발생합니다.
해결책: classifier를 명시적으로 지정해 주세요.
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta"
사례 B: JUnit 4와 JUnit 5의 혼용
테스트 라이브러리 구성 중 구버전 junit-vintage-engine이 포함되어 선택 오류가 나는 경우가 있습니다. 이때는 최신 엔진만 남기고 나머지를 제외하는 설정이 필요합니다.
4. 재발 방지를 위한 베스트 프랙티스
오류를 해결하는 것만큼 중요한 것이 다시 발생하지 않도록 관리하는 것입니다. 전문가들은 다음과 같은 습관을 권장합니다.
- Bill of Materials (BOM) 활용: Spring Boot나 AWS SDK 같은 거대 라이브러리는 BOM을 사용하여 버전 관리를 중앙 집중화하세요.
- 정기적인 의존성 점검:
./gradlew dependencyUpdates(Ben-manes 플러그인 등)를 활용하여 오래되거나 충돌 소지가 있는 의존성을 체크하세요. - 명확한 빌드 스크립트 작성: 가능한 한 동적 버전(예: 1.0.+) 사용을 지양하고 고정 버전을 사용하여 빌드 재현성을 확보하세요.
핵심 요약 정리
- 원인 파악: 빌드 시스템이 동일 라이브러리의 여러 설정(Variant) 중 하나를 고르지 못해 발생.
- 진단 방법:
./gradlew dependencies명령어로 충돌하는 라이브러리 트리 확인. - 해결 방법:
exclude를 통한 중복 모듈 제거constraints를 이용한 특정 버전 강제 지정classifier(예: jakarta) 명시로 모호성 제거
- 예방책: BOM 활용 및 고정 버전 사용을 통해 라이브러리 간 정합성 유지.
이 가이드가 여러분의 빌드 오류 해결에 큰 도움이 되었기를 바랍니다. 만약 특정 라이브러리 조합에서 여전히 문제가 해결되지 않는다면 댓글로 상황을 공유해 주세요. 함께 고민해 보겠습니다!
'오류 > 안드로이드' 카테고리의 다른 글
| Could not find method compile() 오류 해결 방법 [안드로이드 스튜디오] (0) | 2026.01.28 |
|---|---|
| Program type already present 오류 해결 방법 (안드로이드 스튜디오) (0) | 2026.01.11 |
| Could not resolve all attributes 오류 해결 방법 (안드로이드 스튜디오) (0) | 2026.01.09 |
| 안드로이드 스튜디오 - Execution failed for VariantAttr 오류 해결 방법 (0) | 2026.01.08 |
| 안드로이드 스튜디오 - Could not determine the dependencies of task 오류 해결 방법 (0) | 2026.01.07 |