Closed NG-Gaurav closed 5 months ago
I'm facing a very similar issue. When i fire up the request with proguard enabled in R8 fullmode this exception raises:
java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType at retrofit2.HttpServiceMethod.parseAnnotations(SourceFile:46) at retrofit2.ServiceMethod.parseAnnotations(SourceFile:39) at retrofit2.Retrofit.loadServiceMethod(SourceFile:202) at retrofit2.Retrofit$1.invoke(SourceFile:160) at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
I believe that probably is a bug with R8 fullmode enabled. I'm using retrofit 2.9.0 + okHttp3 4.2.0 + square-gson-converter 2.6.1 + kotlin coroutines.
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
See #3579 & #3598.
EDIT: Now you can just simplify use these
Now that Android Studio Flamingo with AGP 8.0 enabled R8 full mode by default, I'm facing the same issue.
Could you please release a new version of Retrofit with the updated consumer rules?
You can just copy-paste the rules https://github.com/square/retrofit/issues/3751#issuecomment-1192043644 into your project.
You can just copy-paste the rules #3751 (comment) into your project.
I know, but not having to maintain R8 rules for third-party libraries is much nicer 😉
@Goooler It doesn't actually work, at least for me with AGP 8.0. After adding this proguard lines I get a slightly different error. Perhaps the reason is in the sandwich library, but I'm not sure:
java.lang.IllegalArgumentException: Unable to create call adapter for retrofit2.Call<com.skydoves.sandwich.ApiResponse>
for method ComicVineService.issues
at retrofit2.Utils.methodError(SourceFile:47)
at retrofit2.HttpServiceMethod.parseAnnotations(SourceFile:394)
at retrofit2.Retrofit.loadServiceMethod(SourceFile:31)
at retrofit2.Retrofit$1.invoke(SourceFile:45)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy9.issues(Unknown Source)
...
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.skydoves.sandwich.adapters.ApiResponseCallAdapterFactory.get(SourceFile:53)
at retrofit2.Retrofit.callAdapter(SourceFile:33)
at retrofit2.HttpServiceMethod.parseAnnotations(SourceFile:375)
... 41 more
@GET("issues?format=$FORMAT&field_list=${Fields.Issues}")
@JvmSuppressWildcards
suspend fun issues(
@Query("api_key") apiKey: String,
@Query("offset") offset: Int,
@Query("limit") limit: Int,
@Query("sort", encoded = true) sort: ComicVineSort?,
@Query("filter[]", encoded = true) filter: List<ComicVineFilter>?,
): ApiResponse<IssuesResponse>
Things about Sandwich will be fixed in https://github.com/skydoves/sandwich/pull/103.
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
See #3579 & #3598.
Hi I have added these rules to my project and still getting the same error, did this work for anyone?
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:46) at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39) at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202) at retrofit2.Retrofit$1.invoke(Retrofit.java:160) at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
The R8 FAQ states the following:
Attributes (such as Signature) and annotations are only kept for classes, methods and fields which are matched by keep rules even when -keepattributes is specified. The weakest rule that will keep annotations and attributes is -keep[classmembers],allowshrinking,allowoptimization,allowobfuscation,allowaccessmodification class-specification Additionally, for attributes describing a relationship such as InnerClass and EnclosingMethod, non-compat mode requires both endpoints being kept.
Does anyone know why the rules in retrofit only contain keep,allowobfuscation,allowshrinking but missing allowoptimization and allowaccessmodification?
The ProGuard documentation states that allowaccessmodification should probably not be used for libraries:
Counter-indication: you probably shouldn't use this option when processing code that is to be used as a library, since classes and class members that weren't designed to be public in the API may become public.
But what about the allowoptimization?
Now that Android Studio Flamingo with AGP 8.0 enabled R8 full mode by default, I'm facing the same issue.
Could you please release a new version of Retrofit with the updated consumer rules?
Did you able to solve it?
Did you able to solve it?
@chiragthummar I just copied these rules into my project but I would still prefer a new Retrofit release 🙏🏼
Thanks you for your answer @svenjacobs
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
Same, have you found the issue? This is my exact issue if it helps - https://stackoverflow.com/questions/76118721/r8-full-mode-throws-class-cast-exception-agp-8-0
ChatGPT gave me this as the answer
The java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType error can occur with Retrofit and Moshi when using R8 full mode because R8 removes the generic type information during the code optimization process. Here's how you can fix this issue:
Add the following Proguard/R8 rule to your proguard-rules.pro file to keep the generic type information:
-keepattributes Signature
If you're using Moshi, add the following Proguard/R8 rule to your proguard-rules.pro file to keep the classes that are used for JSON serialization and deserialization:
-keepclassmembers class com.example.MyClass {
@com.squareup.moshi.FromJson *;
@com.squareup.moshi.ToJson *;
}
Replace com.example.MyClass with the name of your class.
If you're using Kotlin, add the following Proguard/R8 rule to your proguard-rules.pro file to keep the Kotlin metadata:
-keepclassmembers class com.example.MyClass {
kotlin.Metadata <fields>;
}
Replace com.example.MyClass with the name of your class.
If you're still experiencing the issue, you can try using the TypeToken class from the Gson library instead of the ParameterizedType class. To use TypeToken, replace the following code:
Type type = new TypeToken<List<MyClass>>(){}.getType();
with:
Type type = Types.newParameterizedType(List.class, MyClass.class);
Note that you'll need to add the following dependency to your build.gradle file:
implementation 'com.google.code.gson:gson:2.8.9'
Finally, if you're using a custom Moshi JsonAdapter, you can try adding the @JsonClass(generateAdapter = true) annotation to your data class to generate the adapter at compile-time. This can help to avoid issues with R8. For example:
@JsonClass(generateAdapter = true)
data class MyClass(val name: String)
These steps should help you to resolve the java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType error when using Retrofit and Moshi with R8 full mode.
If any of you are using a custom sealed class to represent your API calls state, make sure you include that, as done in the sandwich.pro file in this PR. Your final rules can look like:
# https://github.com/square/okhttp/blob/339732e3a1b78be5d792860109047f68a011b5eb/okhttp/src/jvmMain/resources/META-INF/proguard/okhttp3.pro#L11-L14
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# TODO: Waiting for new retrofit release to remove these rules
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-keep,allowobfuscation,allowshrinking class com.your.company.YourCustomSealedClass
@eury-fsl will try this and get back.
My Working Solutions
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class com.google.gson.reflect.TypeToken
-keep class * extends com.google.gson.reflect.TypeToken
-keep public class * implements java.lang.reflect.Type
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
##---------------End: proguard configuration for Gson ----------
If any of you are using a custom sealed class to represent your API calls state, make sure you include that, as done in the sandwich.pro file in this PR. Your final rules can look like:
# https://github.com/square/okhttp/blob/339732e3a1b78be5d792860109047f68a011b5eb/okhttp/src/jvmMain/resources/META-INF/proguard/okhttp3.pro#L11-L14 -dontwarn okhttp3.internal.platform.** -dontwarn org.conscrypt.** -dontwarn org.bouncycastle.** -dontwarn org.openjsse.** # TODO: Waiting for new retrofit release to remove these rules -keep,allowobfuscation,allowshrinking interface retrofit2.Call -keep,allowobfuscation,allowshrinking class retrofit2.Response -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation -keep,allowobfuscation,allowshrinking class com.your.company.YourCustomSealedClass
Yup, when using https://github.com/arrow-kt/arrow-integrations/tree/main/arrow-integrations-retrofit-adapter arrow adapter which turns the response into and arrow.core.Either<>
I had to add exactly what was said above +
-keep,allowobfuscation,allowshrinking class arrow.core.Either
and it now works
@eury-fsl will try this and get back.
Okay this doesn't work I'm convinced I've got something to deal with Moshi.
This is my issue if anyone has a clue, thanks
Github issue - https://github.com/square/retrofit/issues/3751#issuecomment-1515817159 Stackoverflow - https://stackoverflow.com/questions/76118721/r8-full-mode-throws-class-cast-exception-agp-8-0
@DarkAbhi Can you show me your rules and code for one of your APIs (the interface).
@eury-fsl here, this is my proguard
-keep class com.iku.community_chat.data.room.entity.** { *; }
-keep class androidx.appcompat.widget.** { *; }
#Jsoup
-keep public class org.jsoup.** {
public *;
}
-keepnames class com.iku.user.profile.data.room.models.** { *; }
-keepnames class com.iku.community_courses.data.room.entity.** { *; }
-keeppackagenames org.jsoup.nodes
# 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
-keep,allowobfuscation,allowshrinking class com.squareup.moshi.JsonAdapter
My ApiService
interface IkuApiService {
/**
* Check if email exists
*
* @param email
* @param authorization
* @return
*/
@FormUrlEncoded
@POST("emailcheck")
suspend fun checkIfEmailExists(
@Field("email") email: String,
@Tag authorization: AuthorizationType = AuthorizationType.NONE,
): EmailCheckModel
I have tried to add various rules to try out, this is what it is for now - https://pastebin.com/zJPcJFYT Also trying out @Keep on my models and apiService.
@DarkAbhi Do you have a custom CallAdapter set to retrofit?
@eury-fsl No. This is how I provide my retrofit instances
@Provides
@Singleton
@Keep
fun getIkuRetrofit(moshi: Moshi, okHttpClient: OkHttpClient): IkuApiService {
return Retrofit.Builder()
.baseUrl(Constants.IKU_BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.client(okHttpClient)
.build()
.create(IkuApiService::class.java)
}
@Provides
@Singleton
@Keep
fun getIkuAuthApiRetrofit(
moshi: Moshi,
@Named("for_auth") okHttpClient: OkHttpClient,
): IkuAuthApiService {
return Retrofit.Builder()
.baseUrl(Constants.IKU_BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.client(okHttpClient)
.build()
.create(IkuAuthApiService::class.java)
After clearing cache and invalidating AS, it now worked :)
Even putting the lines below on Proguard:
# -dontwarn kotlin.coroutines.Continuation
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# TODO: Waiting for new retrofit release to remove these rules
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
I still have the issue
Missing class kotlin.coroutines.Continuation (referenced from: java.lang.Object retrofit2.HttpServiceMethod$SuspendForBody.adapt(retrofit2.Call, java.lang.Object[]) and 2 other contexts)
My project doesn't uses Kotlin, it is pure Java 1.8, and it was working before.
Even putting the lines below on Proguard:
# -dontwarn kotlin.coroutines.Continuation -dontwarn okhttp3.internal.platform.** -dontwarn org.conscrypt.** -dontwarn org.bouncycastle.** -dontwarn org.openjsse.** # TODO: Waiting for new retrofit release to remove these rules -keep,allowobfuscation,allowshrinking interface retrofit2.Call -keep,allowobfuscation,allowshrinking class retrofit2.Response -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
I still have the issue
Missing class kotlin.coroutines.Continuation (referenced from: java.lang.Object retrofit2.HttpServiceMethod$SuspendForBody.adapt(retrofit2.Call, java.lang.Object[]) and 2 other contexts)
My project doesn't uses Kotlin, it is pure Java 1.8, and it was working before.
it's a issue with R8 full mode not with java version and with new version of android studio R8 full mode is enabled by default.
android.enableR8.fullMode=false
add this line to your gradle.properties file and it will be working perfectly.
it's a issue with R8 full mode not with java version and with new version of android studio R8 full mode is enabled by default. android.enableR8.fullMode=false
Full mode is there for a reason though. Don't opt out of it when the fix is simply to add a couple more rules to your proguard file
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
See #3579 & #3598.
Wonder why it stopped getting rules from the library - adding these rules manually solved the issue to me.
New proguard rules added but not published yet, you can add these rules to your proguard-rules files. https://github.com/square/retrofit/blob/6cd6f7d8287f73909614cb7300fcde05f5719750/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro#L34-L41
See #3579 & #3598.
Wonder why it stopped getting rules from the library - adding these rules manually solved the issue to me.
Even adding these rules, doesn't worked for me (I'm using Java, not Kotlin)
Update: Adding -dontwarn kotlin.coroutines.Continuation
to proguard's file solved the issue for me.
Mixing these 2 worked for me. New Android Studio ( Android Studio Flamingo | 2022.2.1 Patch 1)
https://github.com/square/retrofit/issues/3751#issuecomment-1525914941
https://github.com/square/retrofit/issues/3751#issuecomment-1192043644
Update: Adding
-dontwarn kotlin.coroutines.Continuation
to proguard's file solved the issue for me.
How would adding -dontwarn
solve your problem? it just doesn't fail the build and swallows the issue imo. Haven't you face any runtime issue on your prod build??
@Hessam-Emami it compiles, but it fails when open on the device.
Adding below lines in proguard-rules.pro
file, fixed the issue for me.
# 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
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# R8 full mode strips generic signatures from return types if not kept.
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
See #3579 & #3598.
FYI, had to add this to consumer-rules.pro
of the module exposing retrofit APIs in Multi module project.
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
See #3579 & #3598.
FYI: This solution working for me. Thank you.
New proguard rules added but not published yet, you can add these rules to your proguard-rules files. https://github.com/square/retrofit/blob/6cd6f7d8287f73909614cb7300fcde05f5719750/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro#L34-L41
See #3579 & #3598.
FYI: This solution working for me. Thank you.
Not work for me :(
This is what worked for me:
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-repackageclasses
# Firebase https://github.com/firebase/firebase-android-sdk/issues/4900
-keep public class com.google.firebase.** { *;}
-keep class com.google.android.gms.internal.** { *;}
-keepclasseswithmembers class com.google.firebase.FirebaseException
# https://github.com/square/retrofit/issues/3751#issuecomment-1564410089
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
# https://github.com/google/gson/commit/43396e45fd1f03e408e0e83b168a72a0f3e0b84e#diff-5da161239475717e284b3a9a85e2f39256d739fb7564ae7fda7f79cee000c413
-keepclasseswithmembers,allowobfuscation,includedescriptorclasses class * {
@com.google.gson.annotations.SerializedName <fields>;
}
note the includedescriptorclasses
.
The suggestions above fixed all but one of my issues, I have a retrofit call that's defined as follow:
@POST("/v2/request/{filename}") suspend fun requestBlah( @Header("Content-Type") contentType: String?, @Path("filename") filename: String?, @Body data: RequestBody? ): ResponseBody
I still get a ClassCastException on that one.
Adding:
-keep,allowobfuscation,allowshrinking class okhttp3.RequestBody -keep,allowobfuscation,allowshrinking class okhttp3.ResponseBody
fixed my remaining problem.
Anyone have this issue with Jackson? Clearly GSON was a known issue but i'm struggling with similar issues
All reflection-based serialization libraries will exhibit problems that require rules to correct.
Yeah got it.
Anyone searching for a fix for the jackson error of java.lang.IllegalArgumentException: Internal error: TypeReference constructed without actual type information
when R8 is enabled in your project when using AGP 8.0.2, this thread has the details ^
Still getting the issue after upgrading to gradle 8.0.2 as well.
Used these progaurd rules.
-keep,allowobfuscation,allowshrinking interface retrofit2.Call -keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
Not working for me.
This is what worked for me:
-keepattributes SourceFile,LineNumberTable -renamesourcefileattribute SourceFile -repackageclasses # Firebase https://github.com/firebase/firebase-android-sdk/issues/4900 -keep public class com.google.firebase.** { *;} -keep class com.google.android.gms.internal.** { *;} -keepclasseswithmembers class com.google.firebase.FirebaseException # https://github.com/square/retrofit/issues/3751#issuecomment-1564410089 -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation -keep,allowobfuscation,allowshrinking interface retrofit2.Call -keep,allowobfuscation,allowshrinking class retrofit2.Response -if interface * { @retrofit2.http.* public *** *(...); } -keep,allowoptimization,allowshrinking,allowobfuscation class <3> # https://github.com/google/gson/commit/43396e45fd1f03e408e0e83b168a72a0f3e0b84e#diff-5da161239475717e284b3a9a85e2f39256d739fb7564ae7fda7f79cee000c413 -keepclasseswithmembers,allowobfuscation,includedescriptorclasses class * { @com.google.gson.annotations.SerializedName <fields>; }
note the
includedescriptorclasses
.
With AGP 8.1, after adding these rules pointed out by Goooler, the missing piece for me was this includedescriptorclasses
modifier on the SerializedName
annotation rule. Thanks @WesleyBatista!
-keepclasseswithmembers,allowobfuscation,includedescriptorclasses class * {
@com.google.gson.annotations.SerializedName <fields>;
}
Note that I'm already keeping all my API data classes anyway, that's probably related.
But it's possible that includedescriptorclasses
modifier is not needed once you add all the missing Gson rules. Also check all your Retrofit rules.
For anyone using jackson googling for this error:
java.lang.IllegalArgumentException: Internal error: TypeReference constructed without actual type information
Read this issue.
On Fri, Jul 7, 2023 at 12:50 PM Jake Wharton @.***> wrote:
All reflection-based serialization libraries will exhibit problems that require rules to correct.
— Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/3751#issuecomment-1625682851, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJ5WJNWABBYCL33CWJ66M3XPA45HANCNFSM5274ZGRQ . You are receiving this because you commented.Message ID: @.***>
Combining officialy commited proguard rules with @digrec's solution worked for me.
# Keep inherited services.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# 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
# R8 full mode strips generic signatures from return types if not kept.
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
# If a class is used in some way by the application, and has fields annotated with @SerializedName
# and a no-args constructor, keep those fields and the constructor
# Based on https://issuetracker.google.com/issues/150189783#comment11
# See also https://github.com/google/gson/pull/2420#discussion_r1241813541 for a more detailed explanation
-if class *
-keepclasseswithmembers,allowobfuscation,allowoptimization class <1> {
<init>();
@com.google.gson.annotations.SerializedName <fields>;
}
So fix for me was to use this rule from retrofit2.pro
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
And remove allowshrinking
from it. Not really sure why. I guess it removed the functions because it seen them as unused? It might be becuase the Interface is provided using Hilt. But all of the functions are used in code so I don't know.
Now I have the rule as follow and it works:
# Retain service method parameters when optimizing.
-keep,allowobfuscation,allowoptimization interface * {
@retrofit2.http.* <methods>;
}
Project is multimodule with Hilt as DI and Moshi as Json convertor. Example of our interface is like this:
internal interface AuthRestApi {
@POST("main/users/login")
suspend fun login(
@Header(NetworkConstant.Header.HEADER_ACCEPT) endpointVersion: String = NetworkConstant.createEndpointVersion(),
@Body request: LoginUserRequest
): Response<LoginResponse>
}
If you have tried all the solutions above and still haven't fixed the issue yet, make sure you have defined this line in every buildTypes
configuration where minifyEnabled true
.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
I resolved this issue by adding the rule from retrofit2.pro to proguard-rules.pro
and defining proguardFiles
in my debug build type.
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# Keep inherited services.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# 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
# R8 full mode strips generic signatures from return types if not kept.
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
# With R8 full mode generic signatures are stripped for classes that are not kept.
-keep,allowobfuscation,allowshrinking class retrofit2.Response
Edited:
If you're using Gson (or a third-party library that depends on Gson) and encounter this new issue:
java.lang.IllegalStateException: TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved.
Try adding this rule:
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
Now that Android Studio Flamingo with AGP 8.0 enabled R8 full mode by default, I'm facing the same issue.
Could you please release a new version of Retrofit with the updated consumer rules?
I'm sorry to ask again but is there a reason why no new version of Retrofit has been released in the past three years? Is this project still maintained?
Accessing hidden method Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V (greylist, reflection, allowed) 16:09:29.013 W java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 16:09:29.014 W at retrofit2.HttpServiceMethod.parseAnnotations(SourceFile:46) 16:09:29.014 W at retrofit2.ServiceMethod.parseAnnotations(SourceFile:39) 16:09:29.014 W at retrofit2.Retrofit.loadServiceMethod(SourceFile:202) 16:09:29.014 W at retrofit2.Retrofit$1.invoke(SourceFile:160) 16:09:29.014 W at java.lang.reflect.Proxy.invoke(Proxy.java:1006) 16:09:29.014 W at $Proxy6.generateAnonymousAuthTokenAsyn(Unknown Source)