Skip to content

@JsonClass(generateAdapter = true) fails when class has field with type Array<Array<T>> with default #1862

@SimoneBari-BS

Description

@SimoneBari-BS

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 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.

Additional notes

Platform: Android 14
Moshi library version: 1.15.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions