Java 11をターゲットにしたAndroidプロジェクトでD8が停止し、Class ... requires its nest host ... to be on program or class path. と表示されることがあります。これは単純な依存関係不足とは限りません。Google Issue TrackerのIssue #490426424では、Android Gradle Plugin(AGP)のannotation extractionによってJava 11のnestmateを構成するクラスが分離され、D8が完全なnestを確認できなくなる不具合として扱われています。公式の修正はAGP 9.2.0に含まれています。
表示されるエラー
Execution failed for task ':app:mergeExtDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate
> There was a failure while executing work items
> A failure occurred while executing com.android.build.gradle.internal.dexing.DexWorkAction
> Failed to process: .../classes.jar
Class com.example.Outer$Nested requires its nest host
com.example.Outer to be on program or class path.
クラス名、タスク名、入力JARはプロジェクトによって変わります。別の形として、Compilation of classes ... requires its nest mates ... to be on program or class path. と表示される場合もあります。重要な検索語は requires its nest host または requires its nest mates です。
原因
Java 11のクラスファイルでは、外部クラスと内部クラスがnest host/nest memberとして関連付けられます。D8がこのバイトコードをデシュガリングするときは、nestを構成するクラス一式をprogram pathまたはclass pathから参照できる必要があります。
Issue #490426424についてGoogleは、AGPが行うannotation extractionが原因だと説明しています。抽出処理でクラスがフィルタリングされると、D8に渡される入力からnest hostまたはnest memberが欠け、整合性検査で上記エラーになります。したがって、ログに名前が出たクラスの依存関係を闇雲に追加しても解決しない場合があります。
対象バージョン:Java 11クラスファイルを扱う、修正前のAGPで発生し得ます。GoogleはAndroid Studio Panda 4 Canary 1同梱のAGP 9.2.0-alpha05でIssue #490426424を修正済みとして掲載し、安定版AGP 9.2.0の修正一覧にも同じIssueを掲載しています。AGP 9.2.0以降を修正版として扱えます。
推奨する解決手順
- 現在のAGPを確認する:ルートの
build.gradle(.kts)またはversion catalogでcom.android.application/com.android.libraryのバージョンを確認します。 - AGP 9.2.0以降へ更新する:同時に、そのAGPが要求するGradleとJDKの互換条件を公式リリースノートで確認します。
- Gradle同期後にクリーンビルドする:古い変換結果を除外するため、Gradleデーモンを止めて対象タスクを再実行します。
plugins DSLの例
plugins {
id("com.android.application") version "9.2.0" apply false
id("com.android.library") version "9.2.0" apply false
}
再確認コマンド
./gradlew --stop
./gradlew clean
./gradlew :app:assembleDebug --stacktrace
すぐに更新できない場合の代替策
- Java 8バイトコードへ一時的に戻す:プロジェクトと依存ライブラリが許す場合は、
sourceCompatibilityとtargetCompatibilityをJavaVersion.VERSION_1_8へ戻すとJava 11 nestmate属性を生成しないため、回避できる可能性があります。ただしJava 11の言語機能・API・ライブラリ要件に影響するため恒久対応には向きません。 - 外部の前処理を確認する:独自タスクやバイトコード処理がJARから内部クラスだけを除外していないか確認し、outer classとinner classを同じ入力またはclass pathに残します。
- 修正版まで現行AGPを維持できない場合:直前に動作していたAGPへ戻す方法もあります。ただしIssueの公式修正は9.2.0なので、最終的には更新を推奨します。
ログに出たnest hostを空のJARとして追加したり、診断だけを抑制したりする方法は避けてください。D8はprivate memberへのnest-based accessを正しく変換するために完全なnestを必要とします。入力が不完全なまま処理を進めると、ビルド後の動作不良につながる可能性があります。
修正できたか確認する方法
./gradlew :app:assembleDebug --stacktraceを実行し、requires its nest hostまたはrequires its nest matesが出ないことを確認します。./gradlew buildEnvironmentやBuild Analyzerで、実際に読み込まれたAGPが9.2.0以降であることを確認します。- debugだけでなく、同じJava 11ライブラリを処理するreleaseビルドとテスト用variantも実行します。
- 一時的にJava 8へ戻した場合は、必要なJava機能と依存ライブラリの互換性テストも行います。
注意点
compileOptionsのJavaバージョン、Gradleを実行するJDK、ライブラリ自身のclass-file versionは別の設定です。どれを変更したか記録してください。- 同じ診断は、AGPの不具合ではなく独自のJAR加工や欠落した依存関係でも発生します。AGP 9.2.0以降でも続く場合は、ログにあるhost/memberの両方が入力に存在するかを確認します。
- キャッシュ削除だけは根本解決ではありません。AGP更新または欠落クラスの復元後に、古い変換物を除外する目的でのみ実施します。
まとめ
Class ... requires its nest host ... to be on program or class path. は、Java 11のnestmateをD8が処理するとき、hostまたはmemberを参照できないことを示します。Issue #490426424ではAGPのannotation extractionが原因で、AGP 9.2.0で修正されています。まずAGP 9.2.0以降へ更新し、クリーンビルドで確認してください。更新できない場合のJava 8化やクラス一式の保持は、影響を検証した上で一時回避として使います。
