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

4

18

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
Unobtrusive answered 22/6, 2023 at 14:29 Comment(1)
Update retrofit version to 2.10.0 or higher and add response-type-keeper annotation processorInspire
H
31

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 
Heathenry answered 16/10, 2023 at 8:19 Comment(2)
The background here is that AGP 8.0 enables R8 full mode by default. For me the rules in this answer fixed the problem.Coadjutor
this should be the accepted answer as of 2024Bradytelic
D
7

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.

Dezhnev answered 5/7, 2023 at 16:21 Comment(0)
C
5

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:

Coadjutor answered 13/12, 2023 at 9:35 Comment(0)
D
0

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.

Dewayne answered 20/3, 2024 at 7:17 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.