IllegalArgumentException due to PrimitiveSerialDescriptor serialName clashes
Describe the bug
After upgrading to 1.4.0 I was seeing runtime crashes originating here https://github.com/Kotlin/kotlinx.serialization/blob/v1.4.0/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt#L66
Amongst others we have a custom serializer for DayOfWeek:
@Serializer(forClass = DayOfWeek::class)
public object DayOfWeekSerializer : KSerializer<DayOfWeek> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(javaClass.simpleName, PrimitiveKind.STRING)
...
Running r8 the obfuscated javaClass.simpleName for DayOfWeekSerializer resulted in being a.
In comparison the obfuscated class names of the built in serializers looked like this:
Obfuscated classname of "Char": Char
Obfuscated classname of "CharArray": CharArray
Obfuscated classname of "Double": Double
Obfuscated classname of "DoubleArray": DoubleArray
Obfuscated classname of "Float": Float
Obfuscated classname of "FloatArray": FloatArray
Obfuscated classname of "Long": Long
Obfuscated classname of "LongArray": LongArray
Obfuscated classname of "Int": Int
Obfuscated classname of "IntArray": IntArray
Obfuscated classname of "Short": Short
Obfuscated classname of "ShortArray": ShortArray
Obfuscated classname of "Byte": Byte
Obfuscated classname of "ByteArray": ByteArray
Obfuscated classname of "Boolean": Boolean
Obfuscated classname of "BooleanArray": BooleanArray
Obfuscated classname of "Unit": t
Obfuscated classname of "Duration": a
Due to the Duration (added in https://github.com/Kotlin/kotlinx.serialization/pull/1960), being obfuscated to a as well this crashed.
For now I fixed this with a proguard rule which keeps the class names of the serializers:
-keepnames class ** extends kotlinx.serialization.KSerializer
Expected behavior
I would have expected that the class names of the built in serializers (Unit and Duration) are not obfuscated, or to have this handled by the recommended proguard rules for Android. Maybe it is also not recommended to rely on javaClass.simpleName for the serialName?
Environment
- Kotlin version: 1.7.10
- Library version: 1.4.0
- Kotlin platforms: JVM
- Gradle version: 7.5.1
I'm not sure it's possible to control the obfuscation pattern on our side, but we'll check if there are any specific rules.
javaClass.simpleName unfortunately is not an option because the core module is multiplatform.
What I don't understand is that the Duration already has it's full pacakge name hardcoded in it's descriptor. I assume that the descriptor names must be unique?
https://github.com/Kotlin/kotlinx.serialization/blob/d5bc32dc11d2a8a08c36663b93839d4fe91f4507/core/commonMain/src/kotlinx/serialization/internal/BuiltInSerializers.kt#L16