Fatal Exception: java.lang.NullPointerException in release build
Asked Answered
I

9

30

I am facing a weird issue in the release build of the app. Here's my exception

Fatal Exception: java.lang.NullPointerException`
throw with null exception
in.hopq.hopq.authentication.models.AppUpdateSourceDO$AppUpdate.getMinAllowedVersion (AppUpdateSourceDO.java:3)
in.hopq.hopq.authentication.activities.SplashActivity$onCreate$1.onChanged (SplashActivity.java:48)
in.hopq.hopq.authentication.activities.SplashActivity$onCreate$1.onChanged (SplashActivity.java:31)

Pojo File

data class AppUpdateSourceDO(
    @SerializedName("app_update")
    val appUpdate: AppUpdate,
    @SerializedName("message")
    val message: String,
    @SerializedName("success")
    val success: Boolean
) {
data class AppUpdate(
        @SerializedName("excluded_versions")
        val excludedVersions: List<ExcludedVersion>,
        @SerializedName("min_allowed_version")
        val minAllowedVersion: Int,
        @SerializedName("min_allowed_version_ios")
        val minAllowedVersionIos: String,
        @SerializedName("recommended_version")
        val recommendedVersion: Int?
) {
    data class ExcludedVersion(
            @SerializedName("version")
            val version: String
    )
}
}

Here's my proguard file

##OKHTTP3
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-dontnote okhttp3.**
-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
Isoelectronic answered 15/5, 2019 at 5:13 Comment(1)
Add @Keep Annotation to your all POJO or Model class to prevent this issue.Latea
I
29

Finally solved this issue. This is because of the new R8 code obfuscation. Simply disable it from your project by adding this to the gradle.properties file

android.enableR8=false

Additionally you add this to your proguard rules file.

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

However adding this to the proguard didn't really worked out.

Isoelectronic answered 15/5, 2019 at 12:16 Comment(5)
Seems that R8 still has this bug issuetracker.google.com/issues/120277396 Hope they fix this soon.Iniquity
@MehulKabaria pleasureIsoelectronic
Is it good to do so for code obfuscation or is there any impact?Suazo
great answer kesarkar sir, but what is enableR8?Bedder
@GunduBandgar R8 is google's new code obfuscation engine similar to proguard.Isoelectronic
U
29

Disabling R8 entirely might not be a good idea. But by adding below lines in your Proguard Rules file might solve the issue --

-keepclassmembers,allowobfuscation class * {
    @com.google.gson.annotations.SerializedName <fields>;
  }
-keep,allowobfuscation @interface com.google.gson.annotations.SerializedName

This is also suggested by one of the Google developers as the desired solution. You can find his answer here and you can also follow the entire discussion around it.

Uhl answered 12/9, 2019 at 9:56 Comment(1)
This solution worked for me. I implemented the first solution of this post and I had compilation problem with Dagger and OKHttp3 when building and signing my app for releaseWriggly
O
10

Seems GSON and R8 don't work well together, and it's written about here:

Actually, the following should also work:

-keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName ; } -keep,allowobfuscation @interface com.google.gson.annotations.SerializedName

That will minify (obfuscate) the names of the fields and the attribute as well, to further reduce the size of the final APK.

In addition, you can see the next rules in the sample of Gson:

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------
Onto answered 3/7, 2019 at 9:9 Comment(0)
A
3

If the @SerializedName annotation is used consistently for data classes the following keep rule can be used

-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
 }

If the @SerializedName annotation is not used the following conservative rule can be used for each data class:

-keepclassmembers class MyDataClass {
  !transient <fields>;
 }

For more info, you can check out below link :-

https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md

Alliaceous answered 25/7, 2019 at 5:35 Comment(0)
A
2

You may need to use

-keepclassmembers enum * { *; }

to keep your enums

Adellaadelle answered 2/3, 2020 at 20:35 Comment(0)
S
2

In my case adding android.enableR8=true to my gradle.properties and -keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName <fields>; } to my proguard-rules.pro did the trick

Shirashirah answered 3/9, 2020 at 12:0 Comment(0)
S
0

I suppose, that you receive null in the json field min_allowed_version because of exception is clearly typed:

Fatal Exception: java.lang.NullPointerException throw with null 
exceptionin.hopq.hopq.authentication.models.AppUpdateSourceDO$AppUpdate.getMinAllowedVersion (AppUpdateSourceDO.java:3)

It means, that when you calling getter of minAllowedVersion field and its returns null - you caught NPE. Try to use null-safety and maybe all will works fine.

data class AppUpdate(
        @SerializedName("excluded_versions")
        val excludedVersions: List<ExcludedVersion> = listOf(),
        @SerializedName("min_allowed_version")
        val minAllowedVersion: Int? = null,
        @SerializedName("min_allowed_version_ios")
        val minAllowedVersionIos: String? = null,
        @SerializedName("recommended_version")
        val recommendedVersion: Int? = null
)
Significancy answered 15/5, 2019 at 5:56 Comment(0)
G
0

Using @Keep annotation can be a reasonable alternative for dealing with proguard files. Just annotate your data class with @Keep and the whole class with its members won't be minified.

It is especially useful when names of all properties match with names of json fields and there is no need to annotate properties with @SerializedName. Proguard rules for classes with @SerializedName annotated fields (mentioned in other answers) are not applicable to such a case.

Gustie answered 19/12, 2019 at 16:19 Comment(0)
R
0

If you update to GSON 2.11.0 then the R8 proguard rules are now included for you.

https://github.com/google/gson/releases/tag/gson-parent-2.11.0

Added default ProGuard / R8 rules If you are using ProGuard or R8 (for example for Android projects) you might not need any special Gson configuration anymore if your classes have a no-args constructor and use @SerializedName for their fields.

You can see them here: https://github.com/google/gson/blob/main/shrinker-test/common.pro

When you depend on this library, the AAR includes the proguard properties files and they are merged into your own, meaning you get the rules by default.

Rolfe answered 31/5, 2024 at 14:53 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.