[Android] CameraX vs Firebase : Guava 삼각관계의 파국

이도연·2025년 8월 24일
0

android studio

목록 보기
31/33

안드로이드 앱을 개발하다 보면 CameraX 와 Firebase 를 동시에 사용하는 경우가 많습니다.
예를 들어, 카메라로 촬영한 이미지를 Firebase Storage 에 업로드하거나,
Firestore 에 메타데이터를 기록하는 경우이죠.

그런데, Firebase 의 의존성을 추가한 순간 갑자기 CameraX 코드에서 이런 에러가 터지는 경험을 한 적 있으신가요?

Cannot access class 'ListenableFuture'. Check your module classpath for missing or conflicting dependencies.

저도 딱 이 문제를 겪었고, 원인을 추적해 보니 흥미로운 사실을 발견했다.
바로 Firebase 와 CameraX 가 같은 라이브러리(Guava)를 서로 다른 방식으로 가져오기 때문에 충돌이 발생한다는 점입니다.


문제의 원인은 Guava

CameraX 의 핵심 클래스인 ProcessCameraProvider.getInstance(context) 는 결과를 ListenableFuture 형태로 반환합니다.
ListenableFuture 는 Google Guava
라는 라이브러리에 들어 있습니다.

  • CameraX → guava-android
  • Firebase → guava-jre

Firebase 의존성을 추가하면서 Gradle 이 guava-jre 를 끌어오면,
CameraX 가 기대하는 guava-android 와 호환되지 않아 ListenableFuture 를 못 찾게 되는 거죠.


해결 방법

1. guava-android 명시적으로 추가

app/build.gradle 의 dependencies 블록에 아래를 넣어줍니다.

dependencies {
    // CameraX
    implementation "androidx.camera:camera-core:1.3.3"
    implementation "androidx.camera:camera-camera2:1.3.3"
    implementation "androidx.camera:camera-lifecycle:1.3.3"
    implementation "androidx.camera:camera-view:1.3.3"

    // Firebase (BOM 사용)
    implementation platform("com.google.firebase:firebase-bom:33.3.0")
    implementation "com.google.firebase:firebase-analytics-ktx"
    implementation "com.google.firebase:firebase-firestore"
    implementation "com.google.firebase:firebase-storage-ktx"

    // Guava Android 변종 강제 적용
    implementation("com.google.guava:guava:31.1-android") {
        force = true
    }
}

여기서 force = true 가 핵심입니다. Gradle 이 Firebase 쪽의 guava-jre 를 가져오더라도, 결국 빌드 시점에는 guava-android 가 적용되도록 보장합니다.


2. 충돌 확인하기

Gradle 의존성 그래프를 직접 확인하면 어떤 버전이 걸려있는지 볼 수 있습니다.

./gradlew app:dependencies --configuration releaseRuntimeClasspath | grep guava

여기서 guava-jre 가 보인다면 Firebase 쪽에서 가져온 겁니다.
최종 빌드에선 반드시 guava-android 만 남도록 조정해야 합니다.

저의 경우, listenablefuture 라는 별도 artifact(Guava 가 쪼개놨던 구버전 모듈)가
9999.0-empty-to-avoid-conflict-with-guava 라는 더미(empty jar) 로 치환된 상태입니다.
이건 Gradle/Maven 쪽에서 중복된 ListenableFuture 클래스 충돌을 막기 위해 일부러 비워놓은 placeholder artifact예요.

그래서 ListenableFuture 클래스를 찾을 수 없다는 오류가 난 거죠.
(-jre 변종이 아니라, listenablefuture 모듈 vs guava-android 모듈 간의 충돌이 원인입니다.)


결론

Firebase 와 CameraX 는 직접적인 상관관계가 없어 보이지만,
공통으로 사용하는 Guava 라이브러리 때문에 간접적으로 충돌이 발생할 수 있습니다.

이 문제를 한 번 겪어보면,
"의존성 충돌" 이라는 게 단순히 버전 차이만이 아니라 "변종(variant)" 의 문제일 수도 있음을 깨닫게 됩니다.

0개의 댓글