Androidアプリ開発でHiltやRoomを導入する際、ksp を利用する場面は多いですが、ある日突然 Unable to load class 'com.google.devtools.ksp.gradle.KspTaskJvm' というエラーに遭遇することがあります。
このエラーは、多くの場合Gradleのプラグイン設定に不備があることが原因です。この記事では、エラーが発生するメカニズムと、その具体的な解決策をまとめます。
TL;DR (結論から)
エラーの直接的な原因は、プロジェクトレベルの build.gradle.kts
に ksp プラグインの定義が欠けていたことでした。app
モジュールで ksp プラグインを利用するには、まずプロジェクト全体で「こういう名前のプラグインが存在しますよ」と宣言しておく必要があります。
修正内容
プロジェクトのルートにある build.gradle.kts
に、以下の行を追加することで解決します。
// build.gradle.kts (Project)
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
id("com.google.dagger.hilt.android") version "2.51.1" apply false
// KSPプラグインをプロジェクト全体で利用可能にするための宣言
alias(libs.plugins.google.ksp) apply false // <- この行を追加!
}
なぜこの一行でエラーが消えるのか? Gradleの仕組みを解説
Gradleの仕組みを理解すると、今回のエラーがなぜ発生し、なぜ解消されたのかが明確になります。ポイントは以下の3つです。
1. Gradleの親子関係: プロジェクトとモジュール
AndroidのGradleプロジェクトは階層構造になっています。
SimpleMemoAppAndroid/ <- 親 (プロジェクトレベル)
├── build.gradle.kts // プロジェクト全体の共通設定ファイル
├── settings.gradle.kts // プロジェクトに含まれるモジュールを定義
└── app/ <- 子 (モジュールレベル)
└── build.gradle.kts // appモジュール固有の設定ファイル
-
親 (プロジェクトレベルの
build.gradle.kts
): プロジェクト全体で利用するライブラリやプラグインのバージョンを一元管理する「司令塔」の役割を担います。 -
子 (モジュールレベルの
build.gradle.kts
): 実際にそのモジュールでどのライブラリやプラグインを「使うか」を指定します。
重要な原則として、子は、親で定義・宣言されたものしか利用できません。
2. apply false の役割: プラグインの「宣言」と「適用」
plugins
ブロックで apply false
を付けると、そのプラグインを**「宣言」だけして「適用」はしない**、という意味になります。
-
宣言 (親で
apply false
): 「このプロジェクトではcom.google.devtools.ksp
という名前のプラグインが利用可能です」とカタログに登録するようなイメージです。これにより、子モジュールがそのプラグインを名前 (alias
) で呼び出せるようになります。 -
適用 (子で
apply false
なし):app/build.gradle.kts
でalias(libs.plugins.google.ksp)
と記述すると、「親で宣言された ksp プラグインを、このapp
モジュールで有効にします(適用します)」という意味になります。
今回のエラーは、親で ksp の「宣言」をしていなかったため、子である app
モジュールが ksp を適用しようとしても「そんなプラグインは知らない」とGradleに怒られていた、というわけです。
3. HiltとKSPの密接な関係
エラーメッセージに ksp
が含まれている通り、これはKSPプラグインが見つからないか、正しく動作していないことを示しています。
Hiltは、DI(依存性注入)を実現するために、コンパイル時に必要なコードを自動生成します。このコード生成の仕組みとして、内部でKSP (Kotlin Symbol Processing) を利用しています。
つまり、HiltをKSPと一緒に使う場合、hilt-android
プラグインと ksp
プラグインの両方が、Gradleに正しく認識されている必要があるのです。
プロジェクトレベルの build.gradle.kts
でHiltプラグイン (com.google.dagger.hilt.android
) だけを宣言し、KSPプラグインを宣言していなかったため、Hiltが動作しようとした際に相方であるはずのKSPのクラスが見つからず、クラスロードエラーが発生していました。
まとめ
Android開発におけるGradleのエラーは一見すると複雑に見えますが、その裏側にある「プロジェクトとモジュールの親子関係」や「プラグインの宣言と適用」という仕組みを理解すると、エラー解決の糸口が見えてきます。
今回の Unable to load class
エラーは、以下の2ステップでプラグイン設定を見直すことで解決に繋がりました。
- 親(プロジェクトレベル)で使う可能性のあるプラグインを
apply false
で宣言する。 - 子(モジュールレベル)で実際に使うプラグインを
apply false
なしで適用する。
HiltやKSPのように、複数のプラグインが協調して動作するライブラリを導入する際は、特にこの親子関係を意識して設定することが重要です。