From e4ea18242ad47cc4525cc5bad5ecf2bd3b145caa Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 10 Mar 2026 09:06:24 +0300 Subject: [PATCH] android: fix missing Hilt GeneratedInjector in asm transform --- android/CHANGELOG.md | 11 +++++++++++ android/app/build.gradle.kts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index 0dc4bdc..255241d 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -983,3 +983,14 @@ - Upgraded attachment audio player behavior (voice + audio): - added seek slider for manual rewind/fast-forward, - unified speed toggle for both `voice` and `audio` playback. + +### Step 134 - Hilt startup crash fix (`MessengerApplication_GeneratedInjector`) +- Fixed startup crash: + - `NoClassDefFoundError: MessengerApplication_GeneratedInjector`. +- Root cause observed in build pipeline: + - `MessengerApplication_GeneratedInjector.class` existed after `javac`, + - but was missing in `transformDebugClassesWithAsm/dirs` before dexing. +- Added Gradle backfill task for `debug/release` variants: + - copies `*Application_GeneratedInjector.class` from `intermediates/javac/.../classes` + into `intermediates/classes/.../transform...ClassesWithAsm/dirs` if missing, + - wired task as dependency of `dexBuilder`. diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 1846dad..456d8fd 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -127,3 +127,37 @@ dependencies { kapt { correctErrorTypes = true } + +fun registerHiltInjectorBackfillTask(variantName: String) { + val cap = variantName.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() } + val taskName = "backfill${cap}HiltApplicationInjector" + val dexBuilderTaskName = "dexBuilder$cap" + val compileJavaTaskName = "compile${cap}JavaWithJavac" + + tasks.register(taskName) { + dependsOn(compileJavaTaskName) + doLast { + val javacOutput = file("$buildDir/intermediates/javac/$variantName/$compileJavaTaskName/classes") + val asmOutput = file("$buildDir/intermediates/classes/$variantName/transform${cap}ClassesWithAsm/dirs") + if (!javacOutput.exists() || !asmOutput.exists()) return@doLast + + fileTree(javacOutput) { + include("**/*Application_GeneratedInjector.class") + }.forEach { source -> + val relativePath = source.relativeTo(javacOutput).path + val target = file("${asmOutput.path}/$relativePath") + if (!target.exists()) { + target.parentFile?.mkdirs() + source.copyTo(target, overwrite = true) + } + } + } + } + + tasks.matching { it.name == dexBuilderTaskName }.configureEach { + dependsOn(taskName) + } +} + +registerHiltInjectorBackfillTask("debug") +registerHiltInjectorBackfillTask("release")