Notes on Proguard when using Kotlin reflect (like jackson-kotlin)

TL;DR
Remember to add the following rules in your proguard.append.cfg if you are using kotlin and kotlin-reflect (for example jackson-module-kotlin) for iOS:

-keepattributes *Annotation*

-keep class kotlin.** { *; }
-keep class org.jetbrains.** { *; }

Explanation

Kotlin compiler uses annotations to store lots of useful runtime informations in class files, for instance the parameters name and nullability of the variable.

Normally the kotlin runtime libraries (kotlin-reflect, stdlib and jetbrains annotations) are provided as external library hens proguard won’t delete anything in those libraries, but things become different in MOE.

MOE uses proguard to combine the dependencies into one single jar file, which means the kotlin runtime jars are provided as ‘-injars’ not ‘-libraryjars’ in the proguard configuration, causes proguard to remove some important annotations and classes from the kotlin runtime, most importantly, the ‘org.jetbrains.annotations.Nullable’ and the annotations storing parameter informations of methods. You may face some weird exceptions like:

com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [XXXX] value failed for JSON property name due to missing (therefore NULL) value for creator parameter null which is a non-nullable type

or

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of XXXX: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)

when you try to deserialize with kotlin data class.

The proguard rules above are simply keep all kotlin and jetbrains stuff. You may optimise them when necessary.

1 Like