본문 바로가기
프로그래밍

Execution failed for task ':app:kaptDebugKotlin'. 오류 해결 방법

by 두꺼비사장 2022. 10. 14.
728x90

안드로이드의 Room을 추가 하고 몇줄 코딩 하자 마자 아래와 같은 빌드 에러가 발생 하였다.

 

Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
   > java.lang.reflect.InvocationTargetException (no error message)

 

안드로이드 room  사용 시 컬럼에 Source라는 맞춤 data class type을 사용하였기 때문이다.

 > 아래 val source: Source

왜냐면 Room은 기본적으로 primitive type(int, short, long ...) 만 지원 하기 때문이다.

data class Source(
    val id: String,
    val name: String
)

 

@Entity(
    tableName = "articles"
)
data class Article(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,
    val author: String,
    val content: String,
    val description: String,
    val publishedAt: String,
    val source: Source,
    val title: String,
    val url: String,
    val urlToImage: String
)

위와 같이 데이터베이스 컬럼에 맞춤 데이터 유형을 사용해야 할 때도 있는데, 이럴때는 TypeConvertes를 사용해야 한다.

 

TypeConvers는 Room이 유지할 수 있는 알려진 유형과 맞춤 데이터를 서로 변환 시켜 준다.

아래와 같이 TypeConverters를 구현해서 넣어 주면 위 빌드 에러를 해결 할 수 있다.

class Converters {

    @TypeConverter
    fun fromSource(source: Source):String {
        return source.name
    }

    @TypeConverter
    fun toSource(name: String): Source {
        return Source(name, name)
    }
}

 

아래는 Annotation TypeConverters를 적용한 code 이다. 

> @TypeConverters(Converters::class)

@TypeConverters(Converters::class)
abstract class ArticleDatabase : RoomDatabase() {

    abstract fun getArticleDao(): ArticleDao

    companion object {
        @Volatile
        private var instance: ArticleDatabase?= null
        private val LOCK = Any()

        operator fun invoke(context: Context) = instance?: synchronized(LOCK) {
            instance?: createDatabase(context).also { instance = it}
        }

        private fun createDatabase(context: Context) =
            Room.databaseBuilder(
                context.applicationContext,
                ArticleDatabase::class.java,
                "article_db.db"
            ).build()
    }
}