#1 문제 상황
#1-1 Hilt 도입
위 게시글에 기반해, 개발 중인 앱에 Hilt를 도입하고 있었다.
#1-2 Application 클래스
package com.example.nutri_capture_new.di
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class HiltApplication : Application()
"com.example.nutri_capture_new"는 내가 개발 중인 프로젝트 이름이다. 여기에 "di" 패키지를 만들고 HiltApplication.kt를 넣었다. Hilt는 Application 클래스를 요구하기 때문이다.
#1-3 에러 메시지
java.lang.RuntimeException: Unable to instantiate application com.example.nutri_capture_new.di.HiltApplication package com.example.nutri_capture_new: java.lang.ClassNotFoundException: Didn't find class "com.example.nutri_capture_new.di.HiltApplication" on path: DexPathList[[zip file "/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk"],nativeLibraryDirectories=[/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/lib/arm64, /data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1574)
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1503)
...
요약하면, HiltApplication 클래스를 찾을 수 없어 런타임 에러가 난다는 말이다.
전체 에러 메시지
java.lang.RuntimeException: Unable to instantiate application com.example.nutri_capture_new.di.HiltApplication package com.example.nutri_capture_new: java.lang.ClassNotFoundException: Didn't find class "com.example.nutri_capture_new.di.HiltApplication" on path: DexPathList[[zip file "/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk"],nativeLibraryDirectories=[/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/lib/arm64, /data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1574)
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1503)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7558)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2400)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.nutri_capture_new.di.HiltApplication" on path: DexPathList[[zip file "/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk"],nativeLibraryDirectories=[/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/lib/arm64, /data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:637)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
at android.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:76)
at androidx.core.app.CoreComponentFactory.instantiateApplication(CoreComponentFactory.java:51)
at android.app.Instrumentation.newApplication(Instrumentation.java:1232)
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1566)
at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1503)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7558)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2400)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Suppressed: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/example/nutri_capture_new/di/Hilt_HiltApplication;
at java.lang.VMClassLoader.findLoadedClass(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:1276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:621)
... 16 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.nutri_capture_new.di.Hilt_HiltApplication" on path: DexPathList[[zip file "/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk"],nativeLibraryDirectories=[/data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/lib/arm64, /data/app/~~V6g0-RtfopAougO3sWY7bA==/com.example.nutri_capture_new-blpUDwYEKGYG8Zyat-1NKA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:637)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
... 19 more
#2 원인 - kapt의 부재
plugins {
...
// KSP (어노테이션 읽기용)
id("com.google.devtools.ksp")
// Hilt
id("com.google.dagger.hilt.android")
}
android {
...
}
dependencies {
...
// Hilt
implementation("com.google.dagger:hilt-android:2.46")
ksp("com.google.dagger:hilt-compiler:2.46")
}
KSP가 kapt의 완전한 상위호환이라고 생각한 것이 문제였다.
Hilt는 dagger2를 더 쉽게 사용하기 위해 만든 추상화 계층이다. 따라서 Hilt는 내부적으로는 dagger2라고 볼 수 있다. 그리고 dagger2는 기본적으로 kapt를 통해 어노테이션(@)을 처리한다. 이후에 KSP가 나왔는데, KSP는 kapt가 읽을 수 있는 어노테이션을 전부 커버하지 못한다. 즉, plungins { ... } 및 dependencies { ... }에 kapt 대신 KSP만 쓰면 읽지 못하는 어노테이션이 존재하게 된다. #1-2에 있는 어노테이션인 @HiltAndroidApp은 KSP로 읽을 수 없고 반드시 kapt로만 읽을 수 있는 어노테이션이기에, 안드로이드 런타임이 그 존재를 감지하지 못했던 것이다.
호환성과 성능을 둘 다 챙기려면 KSP와 kapt를 둘다 추가하면 된다 (#3 참조). 이러면 kapt로 처리해야만 하는 어노테이션은 kapt가 처리하고, 비교적 더 빠른 KSP가 처리할 수 있는 부분은 KSP로 처리하게 된다.
#3 해결
plugins {
...
// KSP 및 kapt (어노테이션 읽기용)
id("com.google.devtools.ksp")
id("org.jetbrains.kotlin.kapt")
// Hilt
id("com.google.dagger.hilt.android")
}
android {
...
}
dependencies {
...
// Hilt
implementation("com.google.dagger:hilt-android:2.46")
kapt("com.google.dagger:hilt-android-compiler:2.46")
ksp("com.google.dagger:hilt-compiler:2.46")
}
#4 소스 코드
에러가 해결된 전체 소스 코드 (개발 중인 앱의 통짜 소스코드)
'개발 일지 > 기타' 카테고리의 다른 글
앞으로의 App 개발 일지 작성 (0) | 2025.01.29 |
---|