google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.41k stars 4.29k forks source link

ArrayList initialized by Gson with a TypeToken returns NullPointerException on android 11 & 12 #2097

Open REInVent650 opened 2 years ago

REInVent650 commented 2 years ago

Gson version

2.9.0 and 2.8.7

Java / Android version

Android 11 & 12 Java 8

Used tools

Description

NullPointerException when trying to add a HashMap to an ArrayList that Gson has initialized with or without data from a json file.

Expected behavior

A HashMap to be added to the ArrayList

Actual behavior

A NullPointerException occured indicating the ArrayList was either null or not of the expected type on Android 11 and 12. Android 10 and below A HashMap is succesfully added to the ArrayList that Gson initialized.

Reproduction steps

Make sure you are using android 11 or 12

ArrayList<HashMap<String, String>> logData;
logData = new Gson().fromJson(filePath, new TypeToken<ArrayList<HashMap<String, String>>>() {}.getType());

Make a new HashMap add it to the ArrayList that Gson has initialized

HashMap<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
logData.add(map);

Exception stack trace

 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference
        at com.mvp.shakeit.ForegroundService.logJson(ForegroundService.java:204)
        at com.mvp.shakeit.ForegroundService.levelTwoWipe(ForegroundService.java:221)
        at com.mvp.shakeit.ForegroundService.lambda$runTask$0$com-mvp-shakeit-ForegroundService(ForegroundService.java:142)
        at com.mvp.shakeit.ForegroundService$$ExternalSyntheticLambda0.onTranslation(Unknown Source:5)
        at com.mvp.shakeit.AccelUtil$1.onSensorChanged(AccelUtil.java:50)
        at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:886)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:335)
        at android.os.Looper.loopOnce(Looper.java:161)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7870)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1019)

I will try and put a MRPE together tomorrow

REInVent650 commented 2 years ago

I did find a workaround for some Android 11 devices, by making this empty class.

public class MyType extends ArrayList<HashMap<String, String>> {
}

then when using from Json I pass it in as the type.

logData = new Gson().fromJson(filePath, MyType.class);

eamonnmcmanus commented 2 years ago

Are you using ProGuard or another code-shrinking solution? Can you say whether the same problem occurs when you don't?

luiges90 commented 1 year ago

Sorry for necro'ing, but we believe that we have also hit a similar issue.

code (Kotlin):

val sessions = gson.fromJson<MutableMap<Int, Triple<UserModel?, Token?, Boolean?>>>(
            sessionsStr,
            object : TypeToken<MutableMap<Int, Triple<UserModel, Token, Boolean>>>() {}.type)

exception:

2022-12-06 10:09:33.591 11381-11381/? W/System.err: ka.w: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BOOLEAN at line 1 column 827 path $..c
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.n$a.read(ReflectiveTypeAdapterFactory.java:14)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.m.b(ReflectiveTypeAdapterFactory.java:1)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.n$c.c(Unknown Source:0)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.n$a.read(ReflectiveTypeAdapterFactory.java:9)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.q.read(Unknown Source:2)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.h$a.read(MapTypeAdapterFactory.java:21)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at ka.i.b(Gson.java:5)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at ka.i.e(Gson.java:4)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at ka.i.d(Unknown Source:4)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at df.y0.invoke(RootInteractor.kt:39)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at bf.b.accept(R8$$SyntheticClass:71)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at io.reactivex.internal.observers.s.onNext(LambdaObserver.java:2)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at io.reactivex.internal.operators.observable.q2$a.run(ObservableObserveOn.java:23)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at io.reactivex.android.schedulers.b$b.run(HandlerScheduler.java:1)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at android.os.Handler.handleCallback(Handler.java:942)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at android.os.Looper.loopOnce(Looper.java:201)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at android.os.Looper.loop(Looper.java:288)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7898)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
2022-12-06 10:09:33.591 11381-11381/? W/System.err: Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BOOLEAN at line 1 column 827 path $..c
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:7)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     at na.n$a.read(ReflectiveTypeAdapterFactory.java:4)
2022-12-06 10:09:33.591 11381-11381/? W/System.err:     ... 21 more
Marcono1234 commented 1 year ago

@luiges90, personally I would treat that as separate issue initially because the stack traces are so different. Could you please create a separate issue for this?

Also, could you please make sure you have configured ProGuard / R8 correctly so it does not obfuscate the field names of your classes. Maybe also try using GsonBuilder.addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_PLATFORM) (requires Gson 2.9.1 or newer) to be sure you don't serialize any Android classes by accident.

Though might be good to further discuss this in a separate GitHub issue.