diff --git a/README.md b/README.md index ae6fedd4c..23daa61ca 100644 --- a/README.md +++ b/README.md @@ -175,12 +175,62 @@ dependencies { ### Android -Library should work on Android "as is". If you're using proguard, you need -to add this to your `proguard-rules.pro`: +The library works on Android, but, if you're using ProGuard, +you need to add rules to your `proguard-rules.pro` configuration to cover all classes that are serialized at runtime. +The following configuration keeps serializers for _all_ serializable classes that are retained after shrinking. +Uncomment and modify the last section in case you're serializing classes with named companion objects. + +```proguard +# Keep `Companion` object fields of serializable classes. +# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects. +-if @kotlinx.serialization.Serializable class ** +-keepclassmembers class <1> { + static <1>$Companion Companion; +} + +# Keep `serializer()` on companion objects (both default and named) of serializable classes. +-if @kotlinx.serialization.Serializable class ** { + static **$* *; +} +-keepclassmembers class <1>$<3> { + kotlinx.serialization.KSerializer serializer(...); +} + +# Keep `INSTANCE.serializer()` of serializable objects. +-if @kotlinx.serialization.Serializable class ** { + public static ** INSTANCE; +} +-keepclassmembers class <1> { + public static <1> INSTANCE; + kotlinx.serialization.KSerializer serializer(...); +} + +# @Serializable and @Polymorphic are used at runtime for polymorphic serialization. +-keepattributes RuntimeVisibleAnnotations,AnnotationDefault + +# Serializer for classes with named companion objects are retrieved using `getDeclaredClasses`. +# If you have any, uncomment and replace classes with those containing named companion objects. +#-keepattributes InnerClasses # Needed for `getDeclaredClasses`. +#-if @kotlinx.serialization.Serializable class +#com.example.myapplication.HasNamedCompanion, # <-- List serializable classes with named companions. +#com.example.myapplication.HasNamedCompanion2 +#{ +# static **$* *; +#} +#-keepnames class <1>$$serializer { # -keepnames suffices; class is kept when serializer() is kept. +# static <1>$$serializer INSTANCE; +#} +``` + +In case you want to exclude serializable classes that are used, but never serialized at runtime, +you will need to write custom rules with narrower [class specifications](https://www.guardsquare.com/manual/configuration/usage). + +
+Example of custom rules + ```proguard --keepattributes *Annotation*, InnerClasses --dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations +-keepattributes RuntimeVisibleAnnotations,AnnotationDefault # kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer -keepclassmembers class kotlinx.serialization.json.** { @@ -208,12 +258,12 @@ to add this to your `proguard-rules.pro`: # Serialization supports named companions but for such classes it is necessary to add an additional rule. # This rule keeps serializer and serializable class from obfuscation. Therefore, it is recommended not to use wildcards in it, but to write rules for each such class. +-keepattributes InnerClasses # Needed for `getDeclaredClasses`. -keep class com.yourcompany.yourpackage.SerializableClassWithNamedCompanion$$serializer { *** INSTANCE; } ``` - -You may also want to keep all custom serializers you've defined. +
### Multiplatform (Common, JS, Native)