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 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.<init> (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.<init> (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
- Add
implementation("com.google.android.gms:play-services-code-scanner:16.1.0")
- Build a release APK with
isMinifyEnabled = true using AGP 9.1.0 (R8 full mode is the default)
- Call
GmsBarcodeScanning.getClient(context, options)
- 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.
Other libraries have had the same issue with AGP 9's R8 full mode:
Bug description
GmsBarcodeScanning.getClient()throws aNullPointerExceptionwhen the app is built with R8 full mode (default in AGP 9+). Debug builds are unaffected. The issue is thatplay-services-code-scanner:16.1.0does 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 for Language ID (
com.google.mlkit.nl.languageid.internal.LanguageIdentificationJni), but for the code scanner API.Stack trace
Environment
play-services-code-scanner:16.1.0compileSdk = 36,targetSdk = 36Steps to reproduce
implementation("com.google.android.gms:play-services-code-scanner:16.1.0")isMinifyEnabled = trueusing AGP 9.1.0 (R8 full mode is the default)GmsBarcodeScanning.getClient(context, options)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.profixes the crash:Expected fix
play-services-code-scannershould ship consumer ProGuard rules in its AAR (viaconsumer-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.Other libraries have had the same issue with AGP 9's R8 full mode: