jdereg / json-io

Convert Java to JSON. Convert JSON to Java. Pretty print JSON. Java JSON serializer. Deep copy Java object graphs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

json-io not working on Android 10

enderk opened this issue · comments

Regarding to Android docs (https://developer.android.com/about/versions/10/non-sdk-q) now value fields removed so reflection based mapping for primitives not working.

Ljava/lang/Boolean;->value:Z # java.lang.Boolean.booleanValue()
Ljava/lang/Byte;->value:B # java.lang.Byte.byteValue()
Ljava/lang/Character;->value:C # java.lang.Character.charValue()
Ljava/lang/Double;->value:D # java.lang.Double.doubleValue()
Ljava/lang/Float;->value:F # java.lang.Float.floatValue()
Ljava/lang/Integer;->value:I # java.lang.Integer.intValue()
Ljava/lang/Long;->value:J # java.lang.Long.longValue()
Ljava/lang/Short;->value:S # java.lang.Short.shortValue()

Workoround: can provide custom serializer for primitive types.

Yes this is a big problem. Oddly, some auto-boxed primitives work (like Long), and others do not (like Integer). Examples:

Run this on an Android 10 or 11 device:

// ArrayList<Long> works fine for serialization
ArrayList<Long> arrayList = new ArrayList<>(Arrays.asList(10L, 20L, 30L, 40L));
String serializedArrayList = JsonWriter.objectToJson(arrayList);
System.out.println("serializedArrayList = " + serializedArrayList); // prints {"@type":"java.util.ArrayList","@items":[10,20,30,40]}

// ArrayList<Integer> serializes to an empty array
ArrayList<Integer> arrayListInts = new ArrayList<>(Arrays.asList(10, 20));
serializedArrayList = JsonWriter.objectToJson(arrayListInts);
System.out.println("serializedArrayList = " + serializedArrayList); // prints {"@type":"java.util.ArrayList","@items":[{"@type":"int"},{"@type":"int"}]}

Android Studio 4 (which uses Java 11) now shows a warning when running a pure unit test that uses json-io library:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.cedarsoftware.util.io.MetaUtils (file:/Users/username/.gradle/caches/modules-2/files-2.1/com.cedarsoftware/json-io/4.10.0/516cde6c4e0207f388ff4b9e979dc86b583ca8c3/json-io-4.10.0.jar) to field java.lang.Integer.value
WARNING: Please consider reporting this to the maintainers of com.cedarsoftware.util.io.MetaUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

I believe the same problem was reported here: #143


As an unrelated point, I noticed that the JsonWriter constructor has duplicate lines to read the property WRITE_LONGS_AS_STRINGS:

https://github.com/jdereg/json-io/blob/31a5c7961c050f7abc6d08011d7e69a1555d4e99/src/main/java/com/cedarsoftware/util/io/JsonWriter.java#L393:L394

public JsonWriter(OutputStream out, Map<String, Object> optionalArgs)
{
    ...
    writeLongsAsStrings = isTrue(args.get(WRITE_LONGS_AS_STRINGS));
    writeLongsAsStrings = isTrue(args.get(WRITE_LONGS_AS_STRINGS));
    ...
}