에러해결하기 - 라이브러리 코드분석하기 feat. 의존성 오류 해결Task :app:lintAnalyzeDebug FAILED

Lee Yongin·2024년 1월 5일
0

리액트 네이티브

목록 보기
6/6

에러

리액트 네이티브의 안드로이드 모듈을 빌드하다가 에러가 나왔다. 저번엔 됐었는데 새로 merge하고 나니 뭐가 또 안 맞았다. task lintAnalyzeDebug라는 게 실패했다.

> Task :app:lintAnalyzeDebug FAILED
w: Detected multiple Kotlin daemon sessions at build/kotlin/sessions

FAILURE: Build failed with an exception.

* What went wrong:
A problem was found with the configuration of task ':app:lintAnalyzeDebug' (type 'AndroidLintAnalysisTask').
  - Gradle detected a problem with the following location: '/Users/yongin/gabojait-react-native/android/app/build/intermediates/ReactNativeVectorIcons'.
    
    Reason: Task ':app:lintAnalyzeDebug' uses this output of task ':app:copyReactNativeVectorIconFonts' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
    
    Possible solutions:
      1. Declare task ':app:copyReactNativeVectorIconFonts' as an input of ':app:lintAnalyzeDebug'.
      2. Declare an explicit dependency on ':app:copyReactNativeVectorIconFonts' from ':app:lintAnalyzeDebug' using Task#dependsOn.
      3. Declare an explicit dependency on ':app:copyReactNativeVectorIconFonts' from ':app:lintAnalyzeDebug' using Task#mustRunAfter.
    
    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.

해결하기

오류 메세지 확인

해결을 하려면 무지성 스택오버플로우 보단 그래들 오류를 봐야 시간을 단축시키는 것 같다(아님말고)
':app:lintAnalyzeDebug'와 ':app:copyReactNativeVectorIconFonts'라는 태스크가 의존성으로 얽혀있는데 암시적인 의존성이기 때문에 오류가 났다는 메시지를 알 수 있었다.

./gradlew lintAnalyzeDebug
./gradlew copyReactNativeVectorIconFonts

언급된 2가지 태스크만 돌렸을 때 성공하는 걸로 봐선 진짜 lintAnalyzeDebug 태스크copyReactNativeVectorIconFonts 태스크 과정 자체의 문제는 아닌 걸 확인할 수 있다.

라이브러리 코드 확인

관련된 스택오버플로우에서 이 그래들 오류에 직접적인 연관이 있는 파일을 수정해야하지만 이미 난 수정된 버전을 패치하고 있는 듯했다. 그렇기 때문에 직접 코드를 분석해보았다.

아무튼 문제가 된 파일은 node_modules/react-native-vector-icons/fonts.gradle 파일이다.
아까 오류메세지에서 언급되었던 두 가지 태스크 간의 의존성이 어떻게 나타나는지도 볼 수 있다. fontCopyTask라는 태스크가 lintVitalAnalyzeTask와 generateAssetsTask로 주입되고 있는데 의존성은 분명 존재하지만 딱히 코드상 문제는 없다.

* Register font asset source folder
 */
android.sourceSets.main.assets.srcDirs += file("$buildDir/intermediates/ReactNativeVectorIcons")

/**
 * Task to copy icon font files
 */
afterEvaluate {
    def config = project.hasProperty("vectoricons") ? project.vectoricons : [];
    def iconFontsDir = config.iconFontsDir ?: "../../node_modules/react-native-vector-icons/Fonts";
    def iconFontNames = config.iconFontNames ?: [ "*.ttf" ];

    def fontCopyTask = tasks.create(
        name: "copyReactNativeVectorIconFonts",
        type: Copy) {
        description = "copy vector icon fonts."
        into "$buildDir/intermediates/ReactNativeVectorIcons/fonts"

        iconFontNames.each { fontName ->
            from(iconFontsDir) {
                include(fontName)
            }
        }
    }

    android.applicationVariants.all { def variant ->
        def targetName = variant.name.capitalize()
        def lintVitalAnalyzeTask = tasks.findByName("lintVitalAnalyze${targetName}")
            if (lintVitalAnalyzeTask) {
                lintVitalAnalyzeTask.dependsOn(fontCopyTask)
            }
        def generateAssetsTask = tasks.findByName("generate${targetName}Assets")
        generateAssetsTask.dependsOn(fontCopyTask)
    }
}

fontCopyTask라는 태스크가 구체적으로 뭘하는지 알고싶기 때문에 빠르게 GPT에게 해석문을 요청했다. GPT는 이럴때 유용하다.

React Native 프로젝트에서 사용되는 벡터 아이콘 폰트를 복사하는 작업을 정의합니다.여기에서 정의된 fontCopyTask는 Gradle의 Copy 타입의 작업으로 생성되었습니다. 이 작업은 copyReactNativeVectorIconFonts라는 이름을 가지며, copy vector icon fonts.라는 설명을 갖고 있습니다.
해당 작업은 iconFontNames라는 리스트에 포함된 각 폰트 이름에 대해 반복하며, iconFontsDir 디렉토리에서 해당 폰트를 선택하여 $buildDir/intermediates/ReactNativeVectorIcons/fonts 디렉토리로 복사합니다.

아래 캡처한 "../../node_modules/react-native-vector-icons/Fonts" 경로의 밑의 파일들을

아래 캡처한 "android/app/build/intermediates/ReactNativeVectorIcon에서 생성해 주는 것 같다.

그래서 ttf파일들을 비우고 다시 빌드해보았더니 똑같은 에러가 나온다(./gradlew clean해도 소용이 없었기 때문에 이럴 줄 알았..)

시도1

뜬금없지만 lint 태스크도 실행해보았다.

./gradlew lint --stacktrace

오류 발견

Lint found 3 errors, 16 warnings. First failure:

/Users/yongin/gabojait-react-native/android/app/src/main/res/values/styles.xml:8: Error: android:forceDarkAllowed requires API level 29 (current min is 21) [NewApi]
        <item name="android:forceDarkAllowed">false</item>
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

minSdkVersion을 21에서 29로 올렸다

buildscript {
    ext {
        buildToolsVersion = "33.0.0"
        minSdkVersion = 29 
        compileSdkVersion = 33
        targetSdkVersion = 33

        // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
        ndkVersion = "23.1.7779620"
    }
    ...중략
}

다시 lint 태스크를 돌렸더니 아래와 같은 에러가 나왔다.
cached image관련해서 적용한 거였는데 일단 MANAGE_DOCUMENTS 권한을 지우고 동작에 이상이 없으면 계속 지워야겠다.

 > Task :app:lintReportDebug
Wrote HTML report to file:///Users/yongin/gabojait-react-native/android/app/build/reports/lint-results-debug.html

> Task :app:lintDebug FAILED
Lint found 1 errors, 17 warnings. First failure:

/Users/yongin/gabojait-react-native/android/app/src/main/AndroidManifest.xml:7: Error: Permission is only granted to system apps [ProtectedPermissions]
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   Explanation for issues of type "ProtectedPermissions":
   Permissions with the protection level signature, privileged or
   signatureOrSystem are only granted to system apps. If an app is a regular
   non-system app, it will never be able to use these permissions.

이후로도 계속 빌드 실패ㅠㅠ

시도2

react-native-vector-icons를 10.0.0에서 10.0.3으로 업데이트 시키고 npx react-native-asset명령을 루트 폴더에서 실행한 후 빌드 해보자

npx react-native-asset

시도3 - 해결완료

이번엔 계속 문제가 되는 react-native-vector-icons 문서를 보면서 초기 설정에 문제가 있었나 확인해보았다.
필수 설정을 해놓은 상태이기 때문에 문제는 보이지 않고 오히려 이걸 지우라는 깃 이슈의 한 댓글(Hit-Opash님)을 보아서 없애고 다시 빌드 했더니 드디어 되었다

react-native-vector-icons의 옵션 설정을 지웠더니 해결되었다.

수정

시도3 방법을 통해 빌드 오류는 해결했지만 api level 29만 font가 정상적으로 보이고 30이상에서는 보이지 않았다. 옵션이 없어진 게 유일한 원인이라 해당 이슈에서 다른 방법을 사용했다.
node_modules/react-native-vector-icons/fonts.gradle 파일의 테스크 의존성을 설정하는 부분에서 아래 코드를 추가했다.
추가해놓고 보니까 이게 맞는 것 같다는 생각이 팍 들긴 함.어이없네

def lintAnalyzeTask = tasks.findByName("lintAnalyze${targetName}")
                lintAnalyzeTask?.dependsOn(fontCopyTask)

이제 빌드도 잘되고 화면렌더링 상에서도 문제가 없게 되었다는 엔딩

보너스

그리고 빌드할 때 아래와 같은 에러가 나는데 이럴 땐 실패한 태스크만 단독으로 돌려주면 성공할 때가 있다. 단독 태스크가 성공하고 나면 전체 빌드때도 실패없이 넘어가니까 시도해보자.

Task :app:mergeReleaseAssets FAILED
ERROR:/Users/yongin/gabojait-react-native/android/app/build/generated/assets/createBundleReleaseJsAndAssets/CodePushHash /Users/yongin/gabojait-react-native/android/app/build/generated/assets/createBundleReleaseJsAndAssets/CodePushHash: Resource and asset merger: Duplicate resources

실패한 태스크를 단독 실행해보면 성공했다.

./gradlew mergeReleaseAssets

다시 빌드를 하면 방금 에러는 없어지고 또 새로운 에러가 나온다.

> Task :app:mergeReleaseStagingAssets FAILED
ERROR:/Users/yongin/gabojait-react-native/android/app/build/generated/assets/createBundleReleaseStagingJsAndAssets/CodePushHash /Users/yongin/gabojait-react-native/android/app/build/generated/assets/createBundleReleaseStagingJsAndAssets/CodePushHash: Resource and asset merger: Duplicate resources

반복진트해서 또 실패한 태스크를 단독 실행하면 성공했다.

./gradlew mergeReleaseStagingAssets
profile
f1을 좋아하는...🏆 f1처럼 빠르고 정확한 걸 좋아하는 안드로이드 개발자

0개의 댓글