종속 항목 해결 오류 디버그

종속 항목을 추가하면 원래 종속 항목에 필요한 종속 항목과 관련된 문제가 발생하고 다른 종속 항목 버전 간에 충돌할 수 있습니다. 종속 항목 그래프를 분석하고 자주 발생하는 문제를 해결하는 방법은 다음과 같습니다.

맞춤 빌드 로직과 관련된 종속 항목 해결 오류를 수정하는 방법에 관한 안내는 맞춤 종속 항목 해결 전략을 참고하세요.

모듈 종속 항목 보기

일부 직접 종속 항목은 자체 종속 항목을 가질 수도 있습니다. 이런 종속 항목을 전이 종속 항목이라고 합니다. 각 전이 종속 항목은 수동으로 선언하지 않아도 Gradle에서 자동으로 수집하여 추가합니다. Gradle용 Android 플러그인에서 주어진 모듈을 위해 Gradle이 해결하는 종속 항목 목록을 표시합니다.

각 모듈의 보고서에서는 또한 빌드 변형, 테스트 소스 세트 및 클래스 경로를 기반으로 종속 항목을 그룹화합니다. 다음은 디버그 빌드 변형의 앱 모듈 런타임 클래스 경로 및 계측 테스트 소스 세트의 컴파일 클래스 경로를 위한 샘플 보고서입니다.

debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...

debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...

이 작업을 실행하려면 다음 절차를 따르세요.

  1. View > Tool Windows > Gradle을 선택하거나 도구 창 모음에서 Gradle 을 클릭합니다.
  2. AppName > Tasks > android를 펼치고 androidDependencies를 더블클릭합니다. Gradle에서 작업을 실행하면 Run 창이 열리고 출력 내용이 표시됩니다.

Gradle의 종속 항목 관리에 관한 자세한 내용은 Gradle 사용자 가이드의 종속 항목 관리 기본사항을 참고하세요.

전이 종속 항목 제외

앱의 범위가 커짐에 따라 앱에 직접 종속 항목과 전이 종속 항목(앱에 가져온 라이브러리가 종속된 라이브러리)을 비롯한 다수의 종속 항목이 포함될 수 있습니다. 더는 필요하지 않은 전이 종속 항목을 제외하려면 다음과 같이 exclude 키워드를 사용하면 됩니다.

Kotlin

dependencies {
    implementation("some-library") {
        exclude(group = "com.example.imgtools", module = "native")
    }
}

Groovy

dependencies {
    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }
}

테스트 구성에서 전이 종속 항목 제외

테스트에서 특정 전이 종속 항목을 제외해야 하는 경우 위에 표시된 코드 샘플이 예상한 대로 작동하지 않을 수 있습니다. 테스트 구성(예: androidTestImplementation)이 모듈의 implementation 구성을 확장하기 때문입니다. 즉 Gradle이 구성을 확인할 때 항상 implementation 종속 항목이 포함됩니다.

따라서 테스트에서 전이 종속 항목을 제외하려면 아래와 같이 실행 시에 제외해야 합니다.

Kotlin

android.testVariants.all {
    compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
    runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
}

Groovy

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

참고: 전이 종속 항목 제외 섹션의 원본 코드 샘플과 같이 종속 항목 블록에서 exclude 키워드를 사용하여 테스트 구성에서만 사용하고 다른 구성에는 포함되지 않는 전이 종속 항목을 생략할 수 있습니다.

종속 항목 해결 오류 수정

앱 프로젝트에 여러 종속 항목을 추가할 때 직접 종속 항목과 전이 종속 항목이 서로 충돌할 수 있습니다. Android Gradle 플러그인에서는 이러한 충돌을 적절히 해결하려고 하지만 일부 충돌은 컴파일 시간 또는 런타임 오류로 이어질 수 있습니다.

어느 종속 항목이 오류의 원인인지 조사하려면 앱 종속 항목 트리를 검사하고 2회 이상 나타나거나 충돌 버전이 있는 종속 항목을 찾습니다.

중복 종속 항목을 쉽게 찾을 수 없으면 다음과 같이 Android 스튜디오의 UI를 사용하여 중복 클래스가 포함된 종속 항목을 검색합니다.

  1. 메뉴 바에서 Navigate > Class를 선택합니다.
  2. 팝업 검색 대화상자에서 Include non-project items 옆에 있는 체크박스가 선택되어 있는지 확인합니다.
  3. 빌드 오류에 표시된 클래스의 이름을 입력합니다.
  4. 클래스가 포함된 종속 항목의 결과를 검사합니다.

다음 섹션에서는 발생할 수 있는 종속 항목 해결 오류의 여러 유형과 해결 방법을 설명합니다.

중복 클래스 오류 수정

한 클래스가 런타임 클래스 경로에 두 번 이상 표시되면 다음과 유사한 오류가 발생합니다.

Program type already present com.example.MyClass

이 오류는 일반적으로 다음과 같은 경우에 발생합니다.

  • 바이너리 종속 항목에 앱에 직접 종속 항목으로 포함된 라이브러리가 포함되어 있습니다. 예를 들어 앱에서 라이브러리 A와 라이브러리 B에 직접 종속 항목을 선언하지만 라이브러리 A의 바이너리에 이미 라이브러리 B가 포함되어 있습니다.
    • 이 문제를 해결하려면 라이브러리 B를 직접 종속 항목에서 삭제합니다.
  • 앱의 동일한 라이브러리에 로컬 바이너리 종속 항목과 원격 바이너리 종속 항목이 있습니다.
    • 이 문제를 해결하려면 바이너리 종속 항목 중 하나를 삭제합니다.

클래스 경로 간 충돌 수정

Gradle이 컴파일 클래스 경로를 해결할 때 먼저 런타임 클래스 경로를 해결하고 그 결과를 사용하여 컴파일 클래스 경로에 추가해야 하는 종속 항목의 버전을 결정합니다. 즉 런타임 클래스 경로에서 다운스트림 클래스 경로의 동일한 종속 항목에 필요한 버전 번호를 결정합니다.

또한 앱의 런타임 클래스 경로에서 Gradle이 앱 테스트 APK의 런타임 클래스 경로에서 종속 항목을 매칭하는 데 필요한 버전 번호를 결정합니다. 그림 1에 클래스 경로의 계층 구조가 설명되어 있습니다.

그림 1. 여러 클래스 경로에 표시되는 종속 항목의 버전 번호는 이 계층 구조에 따라 매칭해야 합니다.

예를 들어 앱에서 implementation 종속 항목 구성을 사용하여 종속 항목의 한 버전을 포함하고 라이브러리 모듈에서는 runtimeOnly 구성을 사용하여 종속 항목의 다른 버전을 포함할 때 여러 클래스 경로에 동일한 종속 항목의 다른 버전이 표시되는 경우 충돌이 발생할 수 있습니다.

런타임 및 컴파일 시간 클래스 경로의 종속 항목을 해결할 때 Android Gradle 플러그인 3.3.0 이상에서는 특정 다운스트림 버전의 충돌을 자동으로 수정하려고 합니다. 예를 들어 런타임 클래스 경로에 라이브러리 A 버전 2.0이 포함되고 컴파일 클래스 경로에 라이브러리 A 버전 1.0이 포함된 경우 플러그인에서 오류를 방지하기 위해 컴파일 클래스 경로의 종속 항목을 라이브러리 A 버전 2.0으로 자동 업데이트합니다.

그러나 런타임 클래스 경로에 라이브러리 버전 1.0이 포함되고 컴파일 클래스 경로에 라이브러리 A 버전 2.0이 포함된 경우에는 플러그인에서 컴파일 클래스 경로의 종속 항목을 라이브러리 A 버전 1.0으로 다운그레이드하지 않으며 다음과 유사한 오류가 계속 발생합니다.

Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.

이 문제를 해결하려면 다음 중 한 가지를 따르세요.

  • 원하는 종속 항목을 라이브러리 모듈에 api 종속 항목으로 포함합니다. 즉 라이브러리 모듈에서만 이 종속 항목을 선언하지만 앱 모듈에서도 라이브러리 모듈의 API에 액세스할 수 있게 됩니다.
  • 또는 두 모듈에 모두 종속 항목을 선언할 수 있지만 각 모듈에서 동일한 버전의 종속 항목을 사용하는지 확인해야 합니다. 프로젝트 전체에서 각 종속 항목의 버전을 일관되게 유지하려면 프로젝트 범위 속성을 구성해 보세요.