java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType with retrofit2

5.3k Views Asked by At

I have this code:

    val profile: UserProfile = userApi.profile()


    @GET("users/profile")
    suspend fun profile(): UserProfile

When i run userApi.profile() i get this error:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
                                                                                                        

Details: I updated gradle, some libraries, kotlin version and android studio. This code used to work before updates. Nothing changed on backend side.

Update: looks like this is happening to all api calls, not just this one.

retrofitVersion = 2.9.0
kotlinVersion = 1.8.10
gradle = 8.0
4

There are 4 best solutions below

0
Holy Rock On

Add these two lines to your proguard rules file

-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

If you don't know what is your proguard rules file, check your app\build.gradle file. There should be a few lines like:

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro",
        )
    }
}

proguard-rules.pro is your proguard rules file.

1
Androidz On

If you check this link https://github.com/square/retrofit/issues/3751 it will tell you to add these in your proguard-rules.pro file

# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items). 
 -keep,allowobfuscation,allowshrinking interface retrofit2.Call 
 -keep,allowobfuscation,allowshrinking class retrofit2.Response 
  
 # With R8 full mode generic signatures are stripped for classes that are not 
 # kept. Suspend functions are wrapped in continuations where the type argument 
 # is used. 
 -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation 
0
Jonik On

The reason why this would happen after update to Android Gradle plugin 8.x is this (from 8.0.0 release notes):

AGP 8.0 enables R8 full mode by default. For more details, see R8 full mode.

For me, the additional -keep,allowobfuscation,allowshrinking rules in this answer fixed the problem.

Alternatively you could explicitly disable full mode by setting this in gradle.properties:

android.enableR8.fullMode=false

That said, it seems preferable to keep full mode on, if possible. Further reading:

0
Yamin On

While other answers are correct, however, I believe they're correct until Retrofit 2.9.0.
After upgrading to Retrofit 2.10.0 again, I encountered a similar error.

java.lang.ClassCastException: java.lang.Object cannot be cast to retrofit2.ServiceMethod

I already added necessary rules for progaurd since 2.9.0 but it didn't matter. I didn't remove those rules yet, but I think those rules are unnecessary since introduction of the retrofit-response-type-keeper. Furthermore, I also used moshi so adding its codegen artifact and annotating all my models with @JsonClass(generateAdapter = true) fixed the problem for me.