lbenedetto
lbenedetto

Reputation: 2114

Proguard/R8 is minifying @JsonProperty annotation names in Kotlin data class for Jackson

I have some classes used for Retrofit2, and serialized by Jackson.

@JsonIgnoreProperties(ignoreUnknown = true)
class GetUserRequest(
    @JsonProperty("user_id")
    var userId: String? = null
)

They work in debug builds, but when I do a release build with proguard or R8 minification enabled, it minifies the classes variables (as expected), but also whatever code is generated by @JsonProperty, causing the network request to be sent with json like { "a": "123" } instead of { "user_id": "123" }

I have included support for kotlin by jackson implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.9" implementation "com.squareup.retrofit2:converter-jackson:2.6.0"

And I have some proguard rules that work for my java class model objects.

-keep class com.fasterxml.jackson.databind.ObjectMapper {
    public <methods>;
    protected <methods>;
}
-keep class com.fasterxml.jackson.databind.ObjectWriter {
    public ** writeValueAsString(**);
}
-keep class * {
     @com.fasterxml.jackson.annotation.JsonCreator *;
     @com.fasterxml.jackson.annotation.JsonProperty *;
}

-keepnames class com.fasterxml.jackson.** { *; }
-dontwarn com.fasterxml.jackson.databind.**
-keep class kotlin.Metadata { *; }

What proguard rules do I need to add so that Proguard does not minify the json properties?

I don't want to just exclude everything in my models package.

Upvotes: 5

Views: 2938

Answers (1)

Victor Cold
Victor Cold

Reputation: 653

I faced the same problem. Solved it like this in your example:

@JsonIgnoreProperties (ignoreUnknown = true)
class GetUserRequest (
     @field:JsonProperty ("user_id")
     var userId: String? = null
)

The annotations from Kotlin data classes like this don't go into java code because, as sgjesse said in comments, in your example the annotation is applied to a constructor parameter, not a field.

You can read more about @field:Annotation here.

P.S:

In my case, this was enough to serialize objects to JSON (to make a request). However, this didn't work in case of deserialization, when receiving a response.

All I needed to add were default parameters for all fields. But you already have it in your example, I'm just writing this for those who will face the same issue.

Upvotes: 5

Related Questions