배경
Room 버전을 2.3.0 에서 2.4.0-alpha03 이상으로 업데이트 해야할 일이 생겼었다.
그런데 버전 올리고 빌드를 돌렸더니 갑자기 coroutine 과 rxjava쪽에서 에러가 발생했다고 뜬다.
컴파일 타임이 아닌 런타임에 에러가 발생했다.
Room을 업데이트하는데 coroutine/rxjava에서 문제가 생겨서 굉장히 뜬금없다고 생각했다.
원인
라이브러리간에 의존성이 꼬여있었기 때문!
kotlinx-coroutines-core의 버전과 kotlinx.coroutines-reactive의 버전은 동일해야한다고 한다. 관련 링크
내가 dependency에 추가한 paging-rxjava3에는 kotlin-coroutines-reactive 가 1.4.3 버전으로 들어가있다. 하지만
room 라이브러리내 kotlin-coroutines-android가 1.5.0 버전으로 dependency가 들어가있고, 이것이 core 버전을 1.5.0으로 올린다. 반면!! reactive는 없다. 따라서 core만 상위 버전으로 올라가 있는 상태이다.
해결하기 위해 reactive의 버전을 명시적으로 core와 일치시키면 된다.(1.5.0 이상으로)
// coroutine
def coroutine_version = "1.5.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutine_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-reactive:$coroutine_version"
해결 방법
해결방법은 위에 적어 놓았지만 이걸 어떻게 캐치하고 원인을 파악할 수 있었는지가 중요하다. 그래야 다음번에 비슷한 라이브러리 의존성문제가 발생하여도 해결할 수 있다.
키워드는 dependency tree이다.
안드로이드 스튜디오의 터미널을 열어 아래의 명령어를 입력한다
./gradlew app:dependencies
그러면 아래와 같이 의존성이 어떻게 되어있는지 보여준다.
내가 이해한 바에 의하면 위의 사진을 이렇게 해석하면 된다. 참고 링크
org.mockito:mockito-inline:2.21.0 의존성을 추가되어 있고(build.gradle) 그 내에 다음의 라이브러리 의존성이 추가되어 있다.
- org.mockito:mockito-core:2.21.0 이 그 내에 추가되어 있다. 하지만 4.0.0으로 자동으로 [버전업]한다. (그 이유는 다른 라이브러리에서 상위 버전의 mockito-core 의 의존성을 추가했기 때문이다) 그리고 org.mockito:mockito-core:4.0.0 내에 포함된 다음의 라이브러리에 의존성을 추가한다.
- net.bytebuddy:byte-buddy:1.11.19
- net.bytebuddy:byte-buddy-agent:1.11.19
dependency tree 읽는 법을 파악하고 나서, 앱의 라이브러리가 어떻게 의존성이 얽혀있는지 보았다.
아래 사진에서 문제가 있음을 인지하는것이 매우매우 중요하다.
위에서 언급했듯이 kotlinx-coroutines-reactive와 kotlinx-coroutines-core의 버전이 일치해야한다는것이 대전제이다. (그렇게 동작하도록 설계되어 있다고 위에 첨부한 이슈의 jetbrain 개발자가 알려줬기 때문)
coroutines-core의 1.4.3 은 1.5.0으로 버전이 올라갔다.(이 이유는 버전이 올라간 room 라이브러리에서 coroutines-core 버전이 올라간걸로 의존성을 걸었기 때문)
그런데 coroutines-reactive는 1.4.3으로 남아있다. 이것이 문제임을 발견하고 명시적으로 버전을 추가하고 나니 이슈없이 잘 빌드되었다.
추가로, terminal에 출력되는 라인이 매우 길 수 있다.
이러한 경우엔 아래와 같이 입력하여 text 파일로 저장할 수 있다.(터미널에서 아무 반응없는것 처럼 보이지만 인내하고 기다려보자)
터미널 현재 경로에 output.txt 파일을 찾을 수 있을 것이다.
./gradlew app:dependencies > output.txt
도움된 사이트
https://github.com/Kotlin/kotlinx.coroutines/issues/2250
문제를 해결하는데에 위 이슈의 댓글들을 하나 하나 읽었던 게 큰 도움이 되었다.
https://mond-al.github.io/dependency-gradle-setup