본문 바로가기

Android/DI

[Hilt] Hilt를 적용할 때 발생할 수 있는 오류.

728x90

본 게시글은 이전 글에 이어서 작성된 부분입니다.

2022.06.18 - [Android/DI] - [Hilt] Koin을 Hilt로 Migration 해보자.

 

이전 글에서 Koin을 Hilt로 Migration을 진행해보았다.

해당 작업을 진행하면서 여러가지 오류를 해결하였는데, 발생했던 오류 내용과 해결하는 방법에 대해서 작성해보고자 한다.


 

우선, 필자가 사용한 Hilt 버전은 2.28-alpha였으며 해당 버전으로 작업을 시작하여서 발생했던 문제라는 것을 먼저 말하고 글을 작성하도록 하겠다.

이전 글을 작성할 때 버전 문제로 인하여 2.36 버전으로 변경하였었는데,

다시 한번 안드로이드 공식 페이지를 참고하여 작업을 하면서 버전에 따라서 발생할 수 있는 오류를 확인하여 작성하였다.

 

 

1. [Hilt] Error

 

error: [Hilt] @DefineComponent dagger.hilt.components.SingletonComponent is missing a parent declaration. Please declare the parent, for example: @DefineComponent(parent = ApplicationComponent.class) [Hilt] Processing did not complete. See error above for details.
[Hilt]

 

빌드 시, 위와 같은 내용으로 오류가 발생하였다.

 

오류 내용에 나온 것으로 검색해보면 @DefineComponent(parent = ApplicationComponent.class) 형태의 어노테이션을 interface에 선언해서 사용해야 한다고 한다.

 

그런데, @DefineComponent에 관련한 정보를 찾아보고 적용해보면 또 다른 오류가 계속해서 발생하고 찾아서 수정하면 또 다른 오류가 발생하면서 정상적으로 진행이 되지 않는다.

 

확인을 해보니, 

Project 범위의 gradle에서 선언된 부분은

 

dependencies {
    ...

    classpath "com.google.dagger:hilt-android-gradle-plugin:2.28-alpha"
}

 

이였으며,

 

Module 범위의 gradle에서는 

 

implementation "com.google.dagger:hilt-android:2.28.3-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28.3-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
kapt 'androidx.hilt:hilt-compiler:1.0.0'

 

이처럼, hilt 버전 자체가 2.28-alpha와 2.28.3-alpha로 버전이 달랐다.

해당 문제는 사용하는 라이브러리와 gradle에서 사용하는 플러그인의 버전이 달라서 발생하는 문제였다.

 

따라서, 동일하게 2.28.3-alpha로 변경을 해주어서 해당 문제를 해결하였다.

 

*

선언한 버전의 차이 뿐 아니라, 2.28-alpha 버전 자체에서도 문제가 있다.

 

 

2. Kotlin Version Error

 

java.lang.IllegalStateException: Unsupported metadata version. Check that your Kotlin version is >= 1.0

 

1번 문제를 해결하고나니 위와 같은 문제가 발생하였다.

코틀린 버전을 1.0 보다 높은 것을 사용하라고 하는데, project 범위의 gradle을 확인해 보면

 

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"

 

이와 같은 버전을 사용하고 있었다.

 

확인을 해보니 플러그인으로 설치 된 Kotlin 버전과 동일한 버전을 사용해주어야 한다고 한다.

PC에서 안드로이드 스튜디오의 환경의 버전을 확인해보니 다음과 같았다.

 

 

1.5.30 버전을 사용하고 있었고, 플러그인 버전과 다른 것을 확인할 수 있었다.

 

따라서 gradle의 버전을 1.5.30으로 맞춰주어서 해결하였다.

필자의 PC와 맥북의 환경이 달라서 발생했던 문제로, 이것을 계기로 버전을 맞추게 되었다.

 

3. MetatData Version Error

 

IllegalStateException: Unsupported metadata version

 

2번과 같이 버전을 맞춰주었을 때 다음과 같은 metatData Version error가 발생할 수 있다.

 

해당 문제는 Dagger는 Kotlin의 1.5.x 버전을 지원하지 않기 때문에 발생하는 문제다.

 

Hilt는 Dagger가 베이스이기 때문에 동일하게 코틀린 버전에 대한 제한이 있다.

따라서 위에서 볼 수 있는 1.5.30 버전을 사용하고 있다면 버전을 맞춰준다고 해도 동일한 문제가 발생하게 된다.

 

이 때, Hilt를 사용하는 모듈의 gradle에 다음과 같은 한 줄을 포함시켜주면 된다.

 

kapt("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0")

 

해당 구문을 통해 버전을 재 정의하여 해결하는 것이라고 하는데,

해당 문제가 발생하는 이유가 Dagger 자체적인 문제이기 때문에, 현재 kotlin 버전은 1.5.x 버전보다 높은 버전이 많이 나왔기 때문에 Kotlin 버전 자체를 올리는 것으로 해결하는 것이 좋을 것이다.

 

4. 매개변수가 있는 ViewModel 사용 시 Instance 오류

 

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.*.*/com.example.*.*.*.*}: java.lang.RuntimeException: Cannot create an instance of class com.example.*.*.*.*

 

* 표시가 되어있는 것은 ViewModel의 Path이다. 

 

3번까지 오류를 모두 수정하게 되면, 정상적으로 빌드가 되고 앱이 실행 된다.

인자가 따로 존재하지 않는 ViewModel을 호출했을 때도 문제 없이 정상적으로 동작 한다.

 

하지만, 인자가 필요한 ViewModel을 호출하는 경우에 앱이 죽고, instance를 생성할 수 없다면서 오류를 뱉는다.

 

외부 라이브러리를 사용하는 부분의 설정이 잘못되어 발생하는 것인가 싶어서 내부 클래스만 사용하도록 변경해서도 확인해 보기도 하였고, 그냥 해당 ViewModel자체의 문제인가 싶어서 모든 인자를 지우고 확인을 해보기도 하였다.

 

 

아무런 인자가 없을 경우 정상적으로 실행되었고, 내부 클래스만 사용하는 경우에도 동일하게 앱이 죽었다.

 

필자는 Instance를 생성할 수 없다고 해서 Module 쪽에서 정상적으로 주입을 해주지 않았나 싶어서 해당 부분을 상당히 많이 찾아보았다. StackOverFlow의 글과 블로그의 찾아보고, Module에 선언한 것들을 방법을 바꿔서 작성해보고, Component를 바꿔보기도 하며 정말 할 수 있는 많은 방법을 사용해 보았지만 동일하게 오류가 발생하였다.

 

따라서 필자와 구조가 비슷한 샘플 예제를 다운 받아서 실행을 해보고, 정상 동작을 하면 구조를 필자의 예제와 동일하도록 점진적으로 변경하면서 확인을 해보며 확인을 했을 때 문제를 발견했다.

 

결과부터 말하자면,

코드의 잘못된 부분은 없었다.

점진적으로 변경하면서, 끝에 필자와 동일한 구조로 변경을 해서 확인을 했을 때도 정상 동작을 하는 것을 확인했다.

그렇다면 다른 부분은 위에서 확인할 수 있었던 버전 문제였고, 필자가 사용하던 2.28.3-alpha 버전은 과거의 버전이고 샘플 코드는 비교적 최신 버전인 것을 확인할 수 있었다.

2.35 버전으로 변경 후, 확인해보니 코드의 수정 없이 정상적으로 동작하는 것을 확인할 수 있었다.

해당 오류가 2.35버전부터 해결 된 것인지는 정확히 확인해보지 않았는데, 예전 버전에서는 오류가 많이 발생하기 때문에 최대한 최신 버전을 사용하는 것이 좋을 것 같다.


필자가 Hilt를 적용하면서 수정했던 오류들은 전부 버전에 관련된 오류들이었다.

필자가 작업할 때 분명히 안드로이드 공식 페이지를 보고 따라서 진행했는데 어째서 이러한 버전 문제가 발생했는지 찾아보았는데,

 

 

안드로이드 공식 페이지에서 2.28-alpha를 사용하여 설명을 작성해두었다.

 

필자도 공식 홈페이지이기 때문에 이것을 그대로 따라가기만 하면 정상 동작을 할 것이라고 생각하고 작업을 진행했던 것이고, 이러한 문제를 맞닥뜨리게 된 것이다.

 

그리고 지금 이 글을 작성하면서,

그러고보니 예전에 다른 것들을 확인했을 때, 영어로 된 가이드는 바로 최신 버전으로 갱신해주고 다른 언어로 번역된 가이드 문서는 최신 버전으로 갱신하지 않았던 것이 생각나서 확인해 보았는데,

 

 

역시 영어의 경우 최신 버전으로 갱신이 되어있고, 그 외 언어에 대해서는 한국어 버전과 동일하게 2.28-alpha로 되어있었다.

 

앞으로는 한국어로 된 가이드 문서를 보더라도, 이해하고 작업하기 전에는 영어로 된 문서를 보고 버전을 한번 더 확인하고 진행해야겠다는 생각이 든다.

 

 

결국 Hilt를 적용하면서 뭔가 잘못 이해해서 발생한 문제라기 보다는 버전에 따른 버그사항이었다는 것이 좀 허탈하다고 생각한다.

하지만, 버전 때문에 이렇게 오류를 수정하는데 시간을 많이 사용한 만큼, 오류가 발생할 수 있는 이유에 라이브러리의 버전 문제도 고려할 수 있게 되었다고 생각하면, 나름 싸게 배운것이 아닌가 생각한다.

 

본 게시글에 사용한 예제는 Github에 올려두었다.

https://github.com/HeeGyeong/CleanArchitectureSample

 

GitHub - HeeGyeong/CleanArchitectureSample

Contribute to HeeGyeong/CleanArchitectureSample development by creating an account on GitHub.

github.com

 

728x90