Why FastJson Crashes with Kotlin Data Classes and How to Fix It
This article examines the challenges of using FastJson, FastJson2, Gson, and Kotlinx-serialization to parse Kotlin data classes in Android, explains why crashes occur due to reflection and null-safety issues, and provides step-by-step solutions—including code modifications, ProGuard rules, and library alternatives—to achieve reliable JSON handling.
Introduction
Since Google released Kotlin in 2017, Android development has shifted from Java to Kotlin. Many legacy projects still use Java data classes and JSON parsers such as FastJson, Gson, etc. When migrating to Kotlin data classes, developers encounter parsing errors, especially after enabling code obfuscation.
Common JSON Parsing Frameworks
FastJson : Alibaba's JSON library, no longer maintained (last version 1.2.83, 2022). Supports Kotlin partially.
FastJson2 : Successor released in 2022, supports Android4, but still relies on reflection.
Gson : Google’s JSON library, uses reflection.
Kotlinx-serialization : Official Kotlin serialization library, generates code at compile time, no reflection.
Problem Scenario
Parsing a JSON string into a Kotlin data class fails with default constructor not found because Kotlin data classes generate only a primary constructor and do not provide a no‑arg constructor or setter methods for val properties. When ProGuard removes the default constructor, FastJson cannot instantiate the class.
FastJson Solution
Modify the data class to use var with default values, add a no‑arg constructor, and keep the class from being obfuscated:
data class ComplexEntity(
var id: Int = 0,
var name: String = "",
var score: Float = 0f,
var userInfo: UserInfo = UserInfo()
)Add ProGuard rules:
-keep class kotlin.reflect.jvm.** {*;}
-keep class * implements java.io.Serializable {*;}FastJson2
FastJson2 behaves the same; it also requires kotlin-reflect for Kotlin data classes. Without it, parsing fails when a JSON field is null for a non‑nullable Kotlin property.
Gson
Gson can parse Kotlin data classes but will assign null to non‑nullable properties, causing runtime exceptions.
Kotlinx-serialization
Kotlinx-serialization does not use reflection. Annotate data classes with @Serializable and add the Kotlin serialization plugin. Example:
@kotlinx.serialization.Serializable
data class ComplexEntity(
val id: Int,
val name: String,
val score: Float,
val userInfo: UserInfo,
val default: Int = 1223
)Configure the JSON parser:
val json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
}Serialize and deserialize:
val jsonString = json.encodeToString(complexEntity)
val obj = json.decodeFromString<ComplexEntity>(jsonString)Utility Wrapper
A Kotlin utility object provides safe APIs for parsing JSON strings to objects, converting objects to JsonElement, and extracting primitive values:
inline fun <reified T> parseObject(jsonStr: String?): T? = jsonStr?.let {
try { json.decodeFromString<T>(it) } catch (e: Exception) { null }
}Additional extension functions for JsonElement such as containsKey, getString, getInt, and getJsonArray simplify data extraction.
Conclusion
When working with Kotlin data classes in Android, FastJson and Gson require reflection and careful ProGuard configuration, while Kotlinx-serialization offers a lightweight, reflection‑free alternative. Refactoring data classes to provide default values or using var properties resolves most parsing crashes.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Smart Platform Tech Team
The Sohu News app's technical sharing hub, offering deep tech analyses, the latest industry news, and fun developer anecdotes. Follow us to discover the team's daily joys.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
