Androidアプリ開発中に遭遇するビルドエラーは、時に開発者を悩ませるものです。
この記事では、実際に発生した複数のビルドエラーに対し、どのように原因を特定し、解決に至ったかの過程をステップバイステップで記録します。
特に、KSP (Kotlin Symbol Processing)、AGP (Android Gradle Plugin)、各種ライブラリのバージョン間依存に起因するエラーに焦点を当てます。
はじめに
最近、ある Android プロジェクトで依存関係の更新を行ったところ、立て続けにビルドエラーに見舞われました。
この記事が、同様の問題に直面している開発者の助けになれば幸いです。
遭遇したエラーとその解決ステップ
エラー1: KSPプラグインが見つからない!(Plugin ... was not found)
Gradle Sync を実行したところ、最初の関門が待っていました。
KotlinBuild file 'C:\...\app\build.gradle.kts' line: 1
Plugin [id: 'com.google.devtools.ksp', version: '2.0.21-1.0.22'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Included Builds (No included builds contain this plugin)
- Plugin Repositories (could not resolve plugin artifact 'com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.21-1.0.22')
Searched in the following repositories:
Google
MavenRepo
Gradle Central Plugin Repository
原因の切り分けと試行錯誤
このエラーは、指定されたバージョンの KSP プラグインが、設定されているリポジトリのどこにも見つからないことを示しています。
-
KSP バージョンと Kotlin バージョンの確認
当初、libs.versions.toml で Kotlin と KSP のバージョン不一致を疑い、KSP のバージョンを Kotlin に合わせて何度か調整。
例:Kotlin 2.0.21 に対し、KSP 2.0.21-1.0.22 → 2.0.20-1.0.22 → 2.0.0-1.0.21 などを試すも改善せず。 -
app/build.gradle.kts の確認
アプリレベルの build.gradle.kts がバージョン直指定になっていないか確認。
alias(libs.plugins.google.ksp) を使用しており問題なし。 -
settings.gradle.kts の確認
ルートの pluginManagement で gradlePluginPortal() が設定されているか確認。問題なし。
// settings.gradle.kts
pluginManagement {
repositories {
google { /* ... */ }
mavenCentral()
gradlePluginPortal() // KSPプラグインはここから取得されるはず
}
}
- AGP バージョンも含めた依存関係の再検討
根本原因として AGP のバージョンの不適切さが浮上。
libs.versions.toml の agp = "8.13.0" はタイプミスであると判明。
解決策:AGP・Kotlin・KSP を互換性ある安定版に統一
最終的に、AGP・Kotlin・KSP を互いに互換性のある組み合わせに修正し解決。
libs.versions.toml の修正差分:
[versions]
- agp = "8.13.0" # ← タイプミスだったバージョン
- kotlin = "2.0.21"
- ksp = "2.0.21-1.0.21" # ← 試行錯誤していたKSPバージョン
+ agp = "8.4.0" # Kotlin 2.0.0 をサポートする安定版AGP
+ kotlin = "2.0.0" # AGP 8.4.0 と互換性のあるKotlinバージョン
+ ksp = "2.0.0-1.0.22" # Kotlin 2.0.0 に対応するKSPバージョン
→ この変更後、Gradle Sync は成功!
教訓:Plugin was not found 系は、プラグイン単体ではなく AGP・Kotlin との組み合わせも必ず確認。
エラー2: ライブラリが新しい AGP を要求!(Dependency ... requires Android Gradle plugin X or higher)
Gradle Sync は通過。しかし、assembleDebug 実行で新たなエラー。
Execution failed for task ':app:checkDebugAarMetadata'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckAarMetadataWorkAction
> 17 issues were found when checking AAR metadata:
1. Dependency 'androidx.compose.foundation:foundation-android:1.9.0' requires Android Gradle plugin 8.6.0 or higher.
This build currently uses Android Gradle plugin 8.4.0.
2. Dependency 'androidx.core:core:1.17.0' requires Android Gradle plugin 8.9.1 or higher.
This build currently uses Android Gradle plugin 8.4.0.
... (同様のエラー多数)
原因の解説:AGP とライブラリのミスマッチ
AGP 8.4.0 / Kotlin 2.0.0 に対し、AndroidX ライブラリが新しすぎる。
AGP を直した際に 他ライブラリのバージョンは据え置き→ 不整合が発生。
解決策:主要ライブラリを現在の AGP・Kotlin に合わせて調整
AGP 8.4.0 / Kotlin 2.0.0 と互換性のある、安定したバージョンに修正。
libs.versions.toml の修正差分:
[versions]
agp = "8.4.0"
kotlin = "2.0.0"
ksp = "2.0.0-1.0.22"
- coreKtx = "1.17.0"
- lifecycleRuntimeKtx = "2.9.3"
- activityCompose = "1.11.0"
- composeBom = "2024.09.00"
- junitVersion = "1.3.0"
- espressoCore = "3.7.0"
+ coreKtx = "1.13.1"
+ lifecycleRuntimeKtx = "2.8.0"
+ activityCompose = "1.9.0"
+ composeBom = "2024.08.00" # Kotlin 2.0.0 に対応するCompose BoM
+ junitVersion = "1.2.1"
+ espressoCore = "3.6.1"
room = "2.6.1" # 変更なし
junit = "4.13.2" # 変更なし
ポイント:[libraries] セクションで、更新後の バージョンエイリアス を正しく参照。
特に Compose は composeBom を platform(...) で導入し、BoMにバージョン管理を委譲。
→ ライブラリの AGP 要求エラーは解消。
教訓:AGP を変えたら、主要ライブラリも総点検。Compose BoM を活用すると管理が楽。
エラー3: Kotlinコードのコンパイルエラー(No value passed for parameter ...)
依存関係の問題は解消。しかし、最後のビルドで Kotlin コードのコンパイルエラー。
In C:\...\app\src\main\java\com\example\simplememoapp_android\ui\screen\MemoScreen.kt, at line 115:
ERROR: No value passed for parameter 'createdAt'.
In C:\...\app\src\main\java\com\example\simplememoapp_android\ui\screen\MemoScreen.kt, at line 178:
ERROR: No value passed for parameter 'createdAt'.
... (同様のエラーが続く)
原因の解説:データクラス変更とプレビューコードの不整合
Memo データクラスの createdAt が**必須(初期値なし)**に変更済み。
// data/model/Memo.kt
@Entity(tableName = "memos")
data class Memo(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val text: String,
val createdAt: LocalDateTime // 初期値なし!
)
一方、MemoScreen.kt の @Preview 用ダミー生成が未対応で、createdAt を渡していないのが原因。
解決策:プレビュー用ダミーデータ生成を修正
MemoScreen.kt のプレビューで、id と createdAt を明示的に指定。
// ui/screen/MemoScreen.kt
@Preview(showBackground = true)
@Composable
fun PreviewMemoItem() {
- MemoItem(memo = Memo(text = "これはプレビュー用のメモです!"))
+ MemoItem(
+ memo = Memo(
+ id = 1, // プレビュー用に適当なID
+ text = "これはプレビュー用のメモです!",
+ createdAt = LocalDateTime.now() // createdAt を追加
+ )
+ )
}
// ...
@Preview(showBackground = true)
@Composable
fun PreviewMemoListSection() {
// ...
val dummyMemos = listOf(
- Memo(text = "キックボクシングに行く"),
- Memo(text = "タリーズで実装する"),
- Memo(text = "夜はジムで筋トレ")
+ Memo(id = 1, text = "キックボクシングに行く", createdAt = LocalDateTime.now()),
+ Memo(id = 2, text = "タリーズで実装する", createdAt = LocalDateTime.now()),
+ Memo(id = 3, text = "夜はジムで筋トレ", createdAt = LocalDateTime.now())
)
// ...
}
必要に応じて import java.time.LocalDateTime を追加)
→ この修正により、全ビルドエラーが解消し無事成功!
教訓:データクラス構造を変更したら、テスト・プレビューも必ず追随。
まとめと教訓
-
エラーメッセージを丁寧に読む
どのファイルで / どの依存関係が問題か のヒントが必ずある。 -
バージョン互換性を常に意識
AGP・Kotlin・KSP・ライブラリは 相互互換が必要。
公式ドキュメントやリリースノートで常に確認。 -
変更は一つずつ・影響を確認
一気に変えると切り分け不能に。Gradle Sync とビルドを小刻みに回す。 -
安定版を使う
理由がなければ alpha / beta より安定版で。 -
libs.versions.toml を活用
依存関係バージョンを一元管理して見通し良く。
ビルドエラーは厄介ですが、ひとつずつ丁寧に対応すれば必ず解決できます。
この記事が、みなさんのトラブルシュートの一助になれば嬉しいです。
付録:解決に至った libs.versions.toml(主要部分)
参考までに、今回の一連のエラーを解決した時点での主要設定を記載します。
[versions]
agp = "8.4.0"
kotlin = "2.0.0"
ksp = "2.0.0-1.0.22"
# AndroidX Core
coreKtx = "1.13.1"
# AndroidX Lifecycle
lifecycleRuntimeKtx = "2.8.0"
# AndroidX Activity
activityCompose = "1.9.0"
# AndroidX Compose
composeBom = "2024.08.00"
# AndroidX Room
room = "2.6.1"
# Testing
junit = "4.13.2"
junitVersion = "1.2.1" # androidx.test.ext:junit
espressoCore = "3.6.1" # androidx.test.espresso:espresso-core
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
# Compose BoM とそれによって管理されるライブラリ
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
# Room
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
google-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
