Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ There are a few open-source projects that can convert Java objects to JSON. Howe
> 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.\
> When using languages other than Java, prefer a JSON library with explicit support for that language.

> [!IMPORTANT]\
> 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.\
> 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).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems we can also mention Moshi here?

Instead look at Kotlin Serialization or Moshi, that use code generation instead of reflection.

Moshi could handle Java classes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressing it to #2857.


### Goals
* Provide simple `toJson()` and `fromJson()` methods to convert Java objects to JSON and vice-versa
* Allow pre-existing unmodifiable objects to be converted to and from JSON
Expand Down
19 changes: 8 additions & 11 deletions Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,18 +398,15 @@ For backward compatibility it is possible to restore Gson's old behavior of allo
- 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.
- 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.

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

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.
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.
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.

However, your classes must adhere to the following:
- must have a no-args constructor\
(and be a top-level or `static` class to avoid implicit constructor arguments)
- 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)
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:

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).
However, this might completely disable some optimizations and obfuscation for these classes.
### Constrain reflected classes
- Ensure all of your objects have a no-arg constructor (and be a top-level or static class to avoid implicit constructor arguments)
- Annotate all fields with `@SerializedName()`

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)),
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.
### Avoid Reflection
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`.