Expo + Android 빌드 실패 트러블슈팅

NARARIA03·2025년 1월 17일
0
post-thumbnail

개요

Expo + RN + IOS 환경에서 열심히 개발하다 AOS 테스트를 진행하려고 빌드를 하는데 갑자기 에러가 발생했다.

지금까지 RN 쓰면서 이런 억까들은 많이 겪었지만, 이번에는 해결하는데 좀 걸렸다.

RN으로 개발할 때마다 느끼지만 GPT는 전혀 도움이 되지 않았고, 공식 문서와 Github issue, Stackoverflow를 뒤져가며 해결했다.

Expo 공식 문서에 트러블슈팅 팁이 있는데, RN 프로젝트를 Android studio로 여는 법이 나와있다.


TL;DR

원인: @react-native-voice/voiceexpo-blur 라이브러리 이슈

두 라이브러리 삭제 후 node_modules, android 폴더를 삭제한 뒤, 다시 빌드해서 해결했다. (백트래킹하며 원인 체크 완료)

rm -rf node_modules
rm -rf android

pnpm remove @react-native-voice/voice
pnpm remove expo-blur

pnpm run android

에러 상황 재현

새 프로젝트를 판 뒤, @react-native-voice/voice를 설치해 상황을 재현해보자. (expo-blur는 기본 포함 라이브러리)

pnpm dlx create-expo-app@latest
cd troubleshoot

pnpm dlx expo install expo-dev-client
pnpm add @react-native-voice/voice

그리고, @react-native-voice/voice 공식 문서 안내대로 app.json을 수정한다.

{
  "expo": {
    ...
    "plugins": [
      ...
      [
        "@react-native-voice/voice",
        {
          "microphonePermission": "CUSTOM: Allow $(PRODUCT_NAME) to access the microphone",
          "speechRecognitionPermission": "CUSTOM: Allow $(PRODUCT_NAME) to securely recognize user speech"
        }
      ]
    ],
    ...
  }
}

그리고, android 에뮬레이터에 빌드해보자.

pnpm run android
> Configure project :expo

Using expo modules
  - expo-asset (11.0.2)
  - expo-blur (14.0.2)
  - expo-constants (17.0.4)
  - expo-dev-client (5.0.9)
  - expo-dev-launcher (5.0.23)
  - expo-dev-menu (6.0.16)
  - expo-file-system (18.0.7)
  - expo-font (13.0.3)
  - expo-haptics (14.0.1)
  - expo-json-utils (0.14.0)
  - expo-keep-awake (14.0.2)
  - expo-linking (7.0.4)
  - expo-manifests (0.15.5)
  - expo-modules-core (2.1.3)
  - expo-splash-screen (0.29.20)
  - expo-system-ui (4.0.7)
  - expo-web-browser (14.0.2)


> Configure project :react-native-reanimated
Android gradle plugin: 8.6.0
Gradle: 8.10.2

> Task :app:checkDebugAarMetadata FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Failed to transform BlurView-version-2.0.3.aar (com.github.Dimezis:BlurView:version-2.0.3) to match attributes {artifactType=android-aar-metadata, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Could not find BlurView-version-2.0.3.aar (com.github.Dimezis:BlurView:version-2.0.3).
        Searched in the following locations:
            https://www.jitpack.io/com/github/Dimezis/BlurView/version-2.0.3/BlurView-version-2.0.3.aar

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.10.2/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 22s
64 actionable tasks: 59 executed, 5 from cache

정확하게 재현되었다.


1. react-native-reanimated ?

로그를 보면, 마치 reanimated 라이브러리의 문제처럼 보인다.

> Configure project :react-native-reanimated
Android gradle plugin: 8.6.0
Gradle: 8.10.2

> Task :app:checkDebugAarMetadata FAILED

그래서 라이브러리 Issue와 Pull Request를 살펴봤으나 별 다른 수확이 없었다.


2. :app:checkDebugAarMetadata ?

GPT에게 물어보고, 구글링을 열심히 했으나, 해당 키워드로는 해결할 수 없었다. (주로 AndroidManifest.xml이나 gradle을 수정하라는 답변이 많았다)

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.

3. (해결) BlurView-version-2.0.3 ?

로그를 보면, Could not find BlurView-version-2.0.3.aar라는 내용이 있다.

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Failed to transform BlurView-version-2.0.3.aar (com.github.Dimezis:BlurView:version-2.0.3) to match attributes {artifactType=android-aar-metadata, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Could not find BlurView-version-2.0.3.aar (com.github.Dimezis:BlurView:version-2.0.3).
        Searched in the following locations:
            https://www.jitpack.io/com/github/Dimezis/BlurView/version-2.0.3/BlurView-version-2.0.3.aar

이를 보고, BlurView라는 라이브러리에서 뭔가를 못 가져오는 문제라고 생각했다.

BlurView는 직접 설치한 라이브러리가 아니기 때문에 구글에 검색해본 결과, Github Issue에 2주 전부터 열린 이슈를 찾을 수 있었다.

라이브러리 개발자가 직접 2.0.3 버전에 해당하는 라이브러리 아티팩트가 사라졌다고 언급했다. 안드로이드 버전(aar)파일이 사라졌기 때문에 AOS에서만 빌드를 실패하는 것으로 보인다.

또, 2.0.4 / 2.0.5 버전 역시 사라졌다고 하며, 버전 업그레이드로 빌드를 성공한 경우는 캐싱 되어있었기 때문이라고 한다. (2.0.6을 사용하라는 의견도 있었다)

나는 해당 라이브러리를 사용하지 않기 때문에, BlurView를 종속성으로 가지는 expo-blur 라이브러리를 제거해보기로 결정했다.

rm -rf node_modules
rm -rf android

pnpm remove expo-blur

pnpm run android

하지만 여전히 빌드에 실패했다.

발생하던 에러가 달라졌으므로 하나는 해결한 것 같다.

> Configure project :expo

Using expo modules
  - expo-asset (11.0.2)
  - expo-constants (17.0.4)
  - expo-dev-client (5.0.9)
  - expo-dev-launcher (5.0.23)
  - expo-dev-menu (6.0.16)
  - expo-file-system (18.0.7)
  - expo-font (13.0.3)
  - expo-haptics (14.0.1)
  - expo-json-utils (0.14.0)
  - expo-keep-awake (14.0.2)
  - expo-linking (7.0.4)
  - expo-manifests (0.15.5)
  - expo-modules-core (2.1.3)
  - expo-splash-screen (0.29.20)
  - expo-system-ui (4.0.7)
  - expo-web-browser (14.0.2)


> Configure project :react-native-reanimated
Android gradle plugin: 8.6.0
Gradle: 8.10.2

> Task :react-native-voice_voice:processDebugManifest
package="com.wenkesj.voice" found in source AndroidManifest.xml: /Users/hyunseong/Documents/troubleshoot/node_modules/@react-native-voice/voice/android/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="com.wenkesj.voice" from the source AndroidManifest.xml: /Users/hyunseong/Documents/troubleshoot/node_modules/@react-native-voice/voice/android/src/main/AndroidManifest.xml.

> Task :app:processDebugMainManifest FAILED
[com.android.support:animated-vector-drawable:28.0.0] /Users/hyunseong/.gradle/caches/8.10.2/transforms/a318293947a7a32df629fcfbe4661082/transformed/animated-vector-drawable-28.0.0/AndroidManifest.xml Warning:
        Namespace 'android.support.graphics.drawable' is used in multiple modules and/or libraries: com.android.support:animated-vector-drawable:28.0.0, com.android.support:support-vector-drawable:28.0.0. Please ensure that all modules and libraries have a unique namespace. For more information, See https://developer.android.com/studio/build/configure-app-module#set-namespace
[androidx.versionedparcelable:versionedparcelable:1.1.1] /Users/hyunseong/.gradle/caches/8.10.2/transforms/631a26a8b0b0832df2135d400f3a11f8/transformed/versionedparcelable-1.1.1/AndroidManifest.xml Warning:
        Namespace 'androidx.versionedparcelable' is used in multiple modules and/or libraries: androidx.versionedparcelable:versionedparcelable:1.1.1, com.android.support:versionedparcelable:28.0.0. Please ensure that all modules and libraries have a unique namespace. For more information, See https://developer.android.com/studio/build/configure-app-module#set-namespace
/Users/hyunseong/Documents/troubleshoot/android/app/src/debug/AndroidManifest.xml:28:18-86 Error:
        Attribute application@appComponentFactory value=(androidx.core.app.CoreComponentFactory) from [androidx.core:core:1.13.1] AndroidManifest.xml:28:18-86
        is also present at [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 value=(android.support.v4.app.CoreComponentFactory).
        Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:6:5-162 to override.

See https://developer.android.com/r/studio-ui/build/manifest-merger for more information about the manifest merger.


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugMainManifest'.
> Manifest merger failed with multiple errors, see logs

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.10.2/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 10s

4. (또) react-native-reanimated ?

로그에 또 react-native-reanimated 라이브러리가 언급된다.

> Configure project :react-native-reanimated
Android gradle plugin: 8.6.0
Gradle: 8.10.2

(나는 이번에도 reanimated 라이브러리 관련 이슈를 뒤져봤지만) 원인은 reanimated 라이브러리가 아니다.


5. Task :app:processDebugMainManifest FAILED ?

로그에 빨간색으로 :app:processDebugMainManifest를 실패했다는 내용이 존재한다.

> Task :app:processDebugMainManifest FAILED
...
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugMainManifest'.

(빨간색에 꽂혀) 해당 키워드로 GPT에게 질문도 해보고 구글링도 해봤지만, AndroidManifest.xml을 수정하라(androidx와 android의 혼용으로 발생?)는 내용만 있고, Expo 관련 이슈는 거의 없었다.


6.(해결) @react-native-voice/voice ?

FAILED 바로 위의 로그를 보면, react-native-voice/voice가 언급된다.

> Task :react-native-voice_voice:processDebugManifest
package="com.wenkesj.voice" found in source AndroidManifest.xml: /Users/hyunseong/Documents/troubleshoot/node_modules/@react-native-voice/voice/android/src/main/AndroidManifest.xml.
Setting the namespace via the package attribute in the source AndroidManifest.xml is no longer supported, and the value is ignored.
Recommendation: remove package="com.wenkesj.voice" from the source AndroidManifest.xml: /Users/hyunseong/Documents/troubleshoot/node_modules/@react-native-voice/voice/android/src/main/AndroidManifest.xml.

해당 라이브러리는 다운로드 수는 많지만, 유지보수가 되고 있지 않은 라이브러리라 프로젝트에서도 expo-speech-recognition으로 마이그레이션 한 상황이었다. Github Issue

때문에 @react-native-voice/voice 라이브러리를 제거한 뒤, app.json의 plugins에서도 제거(안 하면 PluginError 발생)해줬다.

rm -rf node_modules
rm -rf android

pnpm remove @react-native-voice/voice

pnpm run android

이제 정상적으로 빌드 되는 것을 확인할 수 있다!


정리

실제 프로젝트에서 트러블슈팅을 했을 때는 Android studio를 클린 삭제/업데이트한 뒤, Android studio로 빌드 시도를 한 뒤에야 문제점을 파악해 시간이 오래 걸렸었다.

포스팅을 하기 위해 에러를 재현하고 로그를 다시 읽다 느낀 점인데, 내가 에러가 발생(특히 빌드)했을 때 로그를 대충 읽는다는 것을 깨달았다. 빨간 글씨로 강조된 부분 주변만 훑어봐서 BlurViewreact-native-voice 키워드를 눈치채지 못했다.

AOS/IOS 빌드 과정에서 발생하는 에러 로그에서는 힌트를 얻을 수 없었다고 생각했는데, 내 착각이었다. 앞으로는 꼼꼼히 에러 로그를 읽어보려고 한다.

참고로, 아래 명령어도 문제를 일으키는 라이브러리 식별에 도움이 됐다.

pnpm dlx expo install --check|fix # 설치된 패키지 중 업데이트가 필요한 패키지를 확인/해결
pnpm dlx expo-doctor@latest # 프로젝트 내 종속성 등의 문제를 식별하고 해결

글 읽어주셔서 감사합니다. 혹시 최근 Expo + RN을 사용한 프로젝트에서 안드로이드 빌드에 실패하신 분들에게 도움이 되었기를 바랍니다.

이 글에 대한 가독성, 오탈자/오개념, 코드 오타 등 다양한 지적을 환영합니다!


profile
신입 프론트엔드 개발자입니다. React와 RN 생태계를 좋아합니다.

1개의 댓글