Fix: Proguard/R8 configuration for createValueMap #668
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description of the issue
The method
com.segment.analytics.ValueMap#createValueMap
uses reflection to create an instance of the givenClass<T>
. It expects a constructor receiving aMap
.Unfortunately, for some classes like
Address
, this constructor is not used anywhere else in the code so applications using Proguard or R8 to remove unused code will delete this constructor. The outcome is a runtime crash in the application.Here's an example extracted from Firebase Crashlytics in our production application:
How to reproduce
We could not reproduce the exact same execution path of our crash, which goes through the AppboyIntegration library. But we can manually force the crash by invoking the
getValueMap
method:It can be easily reproduced in the sample module by using the snippet above and enabling R8 in the
analytics-samples/build.gradle
file:The proposed fix
We implemented a workaround adding a Proguard rule into our application to stop it from removing code from the Segment SDK.
This PR aims to solve this issue for all consumers of the SDK by providing a
consumerProguardFiles
. The rule in this file keeps classes containing a constructor receiving a map. Proguard/R8 will keep the name of the class from obfuscation and the constructor from being removed.I believe this is just enough to avoid similar crashes, but please double-check the solution.
Here's some more info about the setup: