When testing Moshi CodeGen, I found a weird issue: when a class has a field with type Array<Array<Something>> with a default value, the generated adapter fails to find the correct constructor to create the class instance and deserialization fails with NoSuchMethodException
Here you can find a code snippet replicating the problem:
@Keep
@JsonClass(generateAdapter = true)
data class SerializableClass(
val nestedArray: Array<Array<String>> = emptyArray()
)
fun main() {
val json = "{}"
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(SerializableClass::class.java)
val serializableClass = try {
adapter.fromJson(json)
} catch (e: Exception) {
println("Failed to deserialize class: ${e.message}")
throw e
}
}
Since the JSON doesn't provide the nestedArray value, the generated adapter tries to retrieve the synthetic constructor, but probably uses the wrong type when doing so.
val localConstructor: Constructor<SerializableClass> = this.constructorRef ?:
SerializableClass::class.java.getDeclaredConstructor(ReflectArray.newInstance(KotlinArray::class.java,
0).javaClass, Int::class.javaPrimitiveType, Util.DEFAULT_CONSTRUCTOR_MARKER)
By replacing ReflectArray.newInstance(KotlinArray::class.java,0).javaClass with a simple Array<Array<String>>::class.java, everything works properly.
As a temporary workaround, using Array<List<T>> instead of Array<Array<T>> works correctly.
Hello!
When testing Moshi CodeGen, I found a weird issue: when a class has a field with type
Array<Array<Something>>
with a default value, the generated adapter fails to find the correct constructor to create the class instance and deserialization fails withNoSuchMethodException
Here you can find a code snippet replicating the problem:
Since the JSON doesn't provide the
nestedArray
value, the generated adapter tries to retrieve the synthetic constructor, but probably uses the wrong type when doing so.By replacing
ReflectArray.newInstance(KotlinArray::class.java,0).javaClass
with a simpleArray<Array<String>>::class.java
, everything works properly.As a temporary workaround, using
Array<List<T>>
instead ofArray<Array<T>>
works correctly.Additional notes
Platform: Android 14 Moshi library version: 1.15.1