I'm using Jackson to deserialize Json responses from Retrofit.
I use the Jackson Module Kotlin library for that.
I have data classes with default values for some values that Java represents as primitives, so it won't crash when accessing it without null check.
This all works fine in debug
mode, but when I run on release
with proguard enabled, default values are not set and those values are null, causing my app to crash when accessing them from Java assuming primitives.
I've tried to add every proguard rule I could find online, but with no success.
If anyone has any idea, please share.
Thanks
Example of a data class
data class RideTask(@JsonProperty(RiderFrontendConsts.PARAM_LOCATION)
val location: UserVisibleLocation?,
@JsonProperty(RiderFrontendConsts.PARAM_ETA_TS)
val etaTime: Double?,
@JsonProperty(RiderFrontendConsts.PARAM_TIME_TO_COMPLETION)
val timeToCompletion: Double?,
@JsonProperty(RiderFrontendConsts.PARAM_ETA_DESCRIPTION)
val etaDescription: String?,
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(RiderFrontendConsts.PARAM_INTERNAL_ETA_TS)
val internalEta: Long? = 0,
@JsonProperty(RiderFrontendConsts.PARAM_ETA_DESCRIPTION_LIST)
val etaDescriptionList: List<String>?,
@JsonProperty(RiderFrontendConsts.PARAM_DESCRIPTION_PREFIX)
val descriptionPrefix: String?,
@JsonProperty(RiderFrontendConsts.PARAM_WALKING_DISTANCE_DESCRIPTION)
val walkingDistanceDescription: String?,
@JsonProperty(RiderFrontendConsts.PARAM_WALKING_DISTANCE_IN_METERS)
val walkingDistanceInMeters: Int? = 0)
: Serializable
Retrofit and Jackson initialisation
private Retrofit getRetrofit() {
LOGGER.debug("prepare retrofit");
return new Retrofit.Builder()
.client(getHttpClient(RiderFrontendConsts.DEFAULT_TIMEOUT_IN_MILLIS))
.baseUrl(SettingsManager.getInstance(Application.getInstance()).getServerBaseUrl())
.addConverterFactory(JacksonConverterFactory.create(getObjectMapper()))
.callbackExecutor(Executors.newCachedThreadPool())
.build();
}
private static ObjectMapper getObjectMapper() {
LOGGER.debug("prepare object mapper");
return ExtensionsKt.jacksonObjectMapper()
.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
}
Related pro guard rules
#parsers
-keep class com.fasterxml.jackson.annotation.** { *; }
-dontwarn com.fasterxml.jackson.databind.**
# Kotlin
-keep class kotlin.Metadata { *; }
-keepclassmembers public class via.rider.frontend.** {
public synthetic <methods>;
}
Think the problem is that you have to add a rule in order to keeping the field name, something like
-keep class your.package.model.** { <fields>; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With