moshi: Generic Kotlin data classes cannot be (de)serialized

It seems that Moshi 1.5.0 has a problem with (de)serialization of generic data classes.

data class Test<out T>(val item: T)

data class Test2(val test: Test<String>)

The following code

val json = """{test:{item:"hello"}}"""
val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()
val data = moshi.adapter(Test2::class.java).fromJson(json)

produces the exception

java.lang.IllegalArgumentException: Expected a Class, ParameterizedType, or GenericArrayType, but <null> is of type null
  at com.squareup.moshi.Types.getRawType(Types.java:167)
  at com.squareup.moshi.ClassJsonAdapter$1.createFieldBindings(ClassJsonAdapter.java:83)
  at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:75)
  at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
  at com.squareup.moshi.KotlinJsonAdapterFactory.create(KotlinJsonAdapter.kt:184)
  at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
  at com.squareup.moshi.KotlinJsonAdapterFactory.create(KotlinJsonAdapter.kt:184)
  at com.squareup.moshi.Moshi.adapter(Moshi.java:100)
  at com.squareup.moshi.Moshi.adapter(Moshi.java:62)
  at com.svenjacobs.test.components.main.view.MainActivity.onCreate(MainActivity.kt:24)

This was working in Moshi 1.4.0 and before.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 21
  • Comments: 19 (4 by maintainers)

Most upvoted comments

Can fix.

fixed by #475 for users of the KotlinJsonAdapterFactory.

Please fix this

Yep.

I think it’s too simple. Will try to find time for it.

I can verify this has been fixed for KotlinJsonAdapter in 1.6.0-RC1 for the following sample.

data class Response<Output : Any>(
    val id: String?,
    val result: Output
)

val adapter: JsonAdapter<Response<List<String>>> = moshi.adapter(
    Types.newParameterizedType(
        Response::class.java,  
        Types.newParameterizedType(
            List::class.java, 
            String::class.java
        )
    )
)

adapter.toJson(Response("foo", listOf("bar", "baz"))) // yields: {"id":"foo","result":["bar","baz"]}

Is this bug maintained by now?

What I ended up doing was using AutoValue + auto-value-moshi. You don’t need reflection so it’s gonna be a lot faster if you need to deserialize a ton of models very quickly like JRAW

For that kind of data class, use java to avoid this bug temporarily

Ping, this issue is quite critical.

Anyone knows when the PR above fixing this issue will be merged?

Thanks.