googlesamples / googlesamples/mlkit
play-services-code-scanner crashes with R8 full mode (AGP 9+): missing consumer ProGuard rules
- Dominant language
- Kotlin
- Stars
- 4.3k
- Forks
- 3.1k
- PR merge metrics
- No merged PRs in 30d
Description
## Bug description
`GmsBarcodeScanning.getClient()` throws a `NullPointerException` when the app is built with R8 full mode (default in AGP 9+). Debug builds are unaffected. The issue is that `play-services-code-scanner:16.1.0` does not ship consumer ProGuard rules to protect its internal classes from being stripped by R8.
This is the same class of issue documented on the [ML Kit Known Issues page](https://developers.google.com/ml-kit/known-issues) for Language ID (`com.google.mlkit.nl.languageid.internal.LanguageIdentificationJni`), but for the code scanner API.
## Stack trace
```
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at com.google.android.gms.internal.mlkit_code_scanner.zzny. (play-services-code-scanner@@16.1.0:8)
at com.google.android.gms.internal.mlkit_code_scanner.zzoi.create (play-services-code-scanner@@16.1.0:8)
at com.google.mlkit.common.sdkinternal.LazyInstanceMap.get (LazyInstanceMap.java:3)
at com.google.android.gms.internal.mlkit_code_scanner.zzoj.zza (zzoj.java:2)
at com.google.android.gms.internal.mlkit_code_scanner.zzoj.zzb (zzoj.java:3)
at com.google.mlkit.vision.codescanner.internal.zze. (play-services-code-scanner@@16.1.0:2)
at com.google.mlkit.vision.codescanner.GmsBarcodeScanning.getClient (GmsBarcodeScanning.java:2)
```
## Environment
- `play-services-code-scanner:16.1.0`
- AGP 9.1.0 (R8 full mode enabled by default)
- Gradle 9.4.0
- Kotlin 2.3.10
- Reproducible on: Pixel (Android 16), Samsung Galaxy S26 Ultra (Android 16 Beta), Realme GT6 (Android 16)
- `compileSdk = 36`, `targetSdk = 36`
## Steps to reproduce
1. Add `implementation("com.google.android.gms:play-services-code-scanner:16.1.0")`
2. Build a release APK with `isMinifyEnabled = true` using AGP 9.1.0 (R8 full mode is the default)
3. Call `GmsBarcodeScanning.getClient(context, options)`
4. App crashes with the above NPE
Debug builds (`isMinifyEnabled = false`) work fine — confirming R8 is stripping classes the library needs at runtime.
## Workaround
Adding these keep rules to the app's `proguard-rules.pro` fixes the crash:
```
-keep class com.google.mlkit.** { *; }
-keep class com.google.android.gms.internal.mlkit_code_scanner.** { *; }
```
## Expected fix
`play-services-code-scanner` should ship consumer ProGuard rules in its AAR (via `consumer-rules.pro`) to keep the classes it accesses via reflection. This is the same approach used by other Google libraries and [recommended by Google's own R8 documentation](https://android-developers.googleblog.com/2025/11/configure-and-troubleshoot-r8-keep-rules.html).
Other libraries have had the same issue with AGP 9's R8 full mode:
- [aws-sdk-android#3686](https://github.com/aws-amplify/aws-sdk-android/issues/3686)
- [retrofit#3880](https://github.com/square/retrofit/issues/3880)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.