Skip to content

Commit 3c9abde

Browse files
authored
Add warning about usage of Gson on Android (#2856)
* Add warning about Android usage Adds warning about Android usage on top level readme * Correct Gson formatting * Rewrite warning about R8 / Proguard Discourages use on Android. Some of the previous phrasing is less true now that R8 full mode exists. * Clarify how to avoid reflection in Gson
1 parent 259c477 commit 3c9abde

File tree

2 files changed

+12
-11
lines changed

2 files changed

+12
-11
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ There are a few open-source projects that can convert Java objects to JSON. Howe
1212
> Gson's main focus is on Java. Using it with other JVM languages such as Kotlin or Scala might work fine in many cases, but language-specific features such as Kotlin's non-`null` types or constructors with default arguments are not supported. This can lead to confusing and incorrect behavior.\
1313
> When using languages other than Java, prefer a JSON library with explicit support for that language.
1414
15+
> [!IMPORTANT]\
16+
> Gson is not a recommended library for interacting with JSON on Android. The open ended reflection in the Gson runtime doesn't play nicely with shrinking/optimization/obfuscation passes that Android release apps should perform.\
17+
> If your app or library may be running on Android, instead look at [Kotlin Serialization](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/basic-serialization.md#basics) which uses code generation instead of reflection. This avoids Gson's runtime crashes when optimizations are applied, and results in faster performance on Android devices. If you still want to use Gson and attempt to avoid these crashes, you can see how to do so [here](Troubleshooting.md#-proguard--r8).
18+
1519
### Goals
1620
* Provide simple `toJson()` and `fromJson()` methods to convert Java objects to JSON and vice-versa
1721
* Allow pre-existing unmodifiable objects to be converted to and from JSON

Troubleshooting.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -398,18 +398,15 @@ For backward compatibility it is possible to restore Gson's old behavior of allo
398398
- This does not solve any of the type-safety problems mentioned above; in the long term you should prefer one of the other solutions listed above. This system property might be removed in future Gson versions.
399399
- You should only ever set the property to `"true"`, but never to any other value or manually clear it. Otherwise this might counteract any libraries you are using which might have deliberately set the system property because they rely on its behavior.
400400

401-
## <a id="proguard-r8"></a> ProGuard / R8
401+
## <a id="proguard-r8"></a> Android - R8 / ProGuard
402402

403-
If you use Gson as a dependency in an Android project which uses ProGuard or R8 as code shrinking and obfuscation tool you don't need custom ProGuard rules in most cases.
404-
The Gson-specific rules are [already bundled](gson/src/main/resources/META-INF/proguard/gson.pro) (from Gson 2.11.0) into the Gson JAR which can be interpreted by R8 automatically.
403+
Gson is not recommended on Android due to the expectation of R8 optimization, or other environments where you intend to minify (shrink/optimize/obfuscate) your build, such as with Proguard. While it is possible to make it work with minification, many features of the library will not work in this environment due to the open ended reflection performed in Gson. This is true even with the most up to date Proguard file, included in Gson 2.11.0.
405404

406-
However, your classes must adhere to the following:
407-
- must have a no-args constructor\
408-
(and be a top-level or `static` class to avoid implicit constructor arguments)
409-
- fields must be annotated with [`@SerializedName`](https://javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/annotations/SerializedName.html)
405+
If you do want to make Gson work with minification, you must test your code after minification has been applied, and can choose to either:
410406

411-
Alternatively you can configure ProGuard or R8 to keep your classes as they are, for example by [specifying custom ProGuard rules or by using `@Keep` on the classes](https://developer.android.com/build/shrink-code#keep-code).
412-
However, this might completely disable some optimizations and obfuscation for these classes.
407+
### Constrain reflected classes
408+
- Ensure all of your objects have a no-arg constructor (and be a top-level or static class to avoid implicit constructor arguments)
409+
- Annotate all fields with `@SerializedName()`
413410

414-
If you still use a Gson version older than 2.11.0 or if you are using ProGuard for a non-Android project ([related ProGuard issue](https://github.com/Guardsquare/proguard/issues/337)),
415-
you may need to copy the rules from the [`gson.pro`](gson/src/main/resources/META-INF/proguard/gson.pro) file into your own ProGuard configuration file.
411+
### Avoid Reflection
412+
It is possible to avoid reflection when using Gson. This will mean you will need to have a `TypeAdapter` or `TypeAdapterFactory` for every type you might want to serialize or deserialize, or that you are only using Gson through its explicit JSON API via classes like `JsonObject` and `JsonArray`. You can ensure reflection isn't being used by calling [addReflectionAccessFilter()](https://javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/GsonBuilder.html#addReflectionAccessFilter(com.google.gson.ReflectionAccessFilter)) to add a filter which always returns `BLOCK_ALL`.

0 commit comments

Comments
 (0)