Reputation: 808
I recently upgraded to Android Studio Flamingo and AGP 8.0
My production builds with minfiy and shrinkResources enabled, doesn't allow retrofit to make calls. This is the error thrown.
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)
at $Proxy11.checkIfEmailExists(Unknown Source)
at com.iku.data.network.service.IkuApiService$DefaultImpls.checkIfEmailExists$default(IkuApiService.kt:123)
at com.iku.auth.data.network.repository.AuthRepositoryImpl$checkEmail$2.invokeSuspend(AuthRepositoryImpl.kt:24)
at com.iku.auth.data.network.repository.AuthRepositoryImpl$checkEmail$2.invoke(AuthRepositoryImpl.kt:0)
at com.iku.auth.data.network.repository.AuthRepositoryImpl$checkEmail$2.invoke(AuthRepositoryImpl.kt:0)
at com.iku.data.network.helper.NetworkHelperKt$safeApiCall$2.invokeSuspend(NetworkHelper.kt:27)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
I found this issue on retorfit's github - https://github.com/square/retrofit/issues/3751. And have added the new rules has commented here - https://github.com/square/retrofit/issues/3751#issuecomment-1192043644
# 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
But this doesn't solve the issue. Any help would be apprecaited.
My proguard-rules.pro
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-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
The gradle file
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: "androidx.navigation.safeargs.kotlin"
// Detekt
apply plugin: "io.gitlab.arturbosch.detekt"
// Apply the Crashlytics Gradle plugin
apply plugin: 'com.google.firebase.crashlytics'
// Apply the Performance Monitoring plugin
apply plugin: 'com.google.firebase.firebase-perf'
// Dokka
apply plugin: 'org.jetbrains.dokka'
android {
packagingOptions {
resources.excludes.add("META-INF/*")
}
signingConfigs {
release {
storeFile = rootProject.file("a.jks")
storePassword System.getenv("SIGNING_STORE_PASSWORD")
keyAlias System.getenv("SIGNING_KEY_ALIAS")
keyPassword System.getenv("SIGNING_KEY_PASSWORD")
}
}
compileSdkVersion 33
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.iku"
minSdkVersion 24
targetSdkVersion 33
versionCode 77
versionName "0.3.228"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Properties properties = new Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
}
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
buildTypes {
debug {
applicationIdSuffix ".test"
minifyEnabled true
shrinkResources true
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
viewBinding true
dataBinding true
}
kapt {
javacOptions {
// These options are normally set automatically via the Hilt Gradle plugin, but we
// set them manually to workaround a bug in the Kotlin 1.5.20
option("-Adagger.fastInit=ENABLED")
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}
}
namespace 'com.iku'
}
dependencies {
def lifecycle_version = "2.6.1"
def room_version = "2.5.1"
def camerax_version = '1.3.0-alpha05'
def work_version = '2.8.1'
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_version"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation fileTree(dir: "libs", include: ["*.jar"])
api 'com.google.android.material:material:1.8.0'
implementation 'com.google.android.gms:play-services-auth:20.5.0'
implementation 'com.google.android.gms:play-services-basement:18.2.0'
implementation 'com.google.android.play:core:1.10.3'
implementation 'com.google.maps.android:maps-ktx:3.4.0'
implementation 'com.google.maps.android:maps-utils-ktx:3.2.0'
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.libraries.places:places:3.0.0'
// Firebase
implementation 'com.google.firebase:firebase-crashlytics-ktx:18.3.6'
implementation 'com.google.firebase:firebase-messaging:23.1.2'
implementation 'com.google.firebase:firebase-perf:20.3.1'
implementation 'com.google.firebase:firebase-analytics-ktx:21.2.1'
implementation 'com.facebook.shimmer:shimmer:0.5.0'
// Java language implementation
implementation 'androidx.fragment:fragment-ktx:1.5.6'
implementation "androidx.activity:activity-ktx:1.7.0"
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "androidx.paging:paging-runtime-ktx:3.1.1"
implementation "androidx.recyclerview:recyclerview:1.3.0"
implementation "androidx.core:core-ktx:1.9.0"
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation 'androidx.emoji:emoji:1.1.0'
implementation 'androidx.emoji:emoji-appcompat:1.1.0'
implementation 'androidx.emoji:emoji-bundled:1.1.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation 'androidx.exifinterface:exifinterface:1.3.6'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.preference:preference-ktx:1.2.0"
implementation 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03'
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
implementation("androidx.security:security-crypto:1.0.0")
implementation 'androidx.window:window:1.0.0'
// Flexbox
implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4'
// Third party
implementation('io.coil-kt:coil:2.2.0')
implementation 'com.airbnb.android:lottie:6.0.0'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'nl.dionsegijn:konfetti:1.3.2'
implementation 'me.saket:better-link-movement-method:2.2.0'
implementation 'org.jsoup:jsoup:1.14.3'
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.github.skydoves:balloon:1.5.3'
api 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
implementation 'com.hbb20:ccp:2.5.4'
// Life cycle
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Data store
implementation 'androidx.datastore:datastore-preferences:1.0.0'
implementation 'androidx.datastore:datastore:1.0.0'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7'
//OKHttp Interceptor
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.7'
// Moshi
implementation 'com.squareup.moshi:moshi-kotlin:1.14.0'
kapt("com.squareup.moshi:moshi-kotlin-codegen:1.14.0")
// Support for Java 8 features
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
// Work Manager Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// Room Paging 3 Integration
implementation "androidx.room:room-paging:$room_version"
// hilt
implementation 'com.google.dagger:hilt-android:2.45'
kapt 'com.google.dagger:hilt-android-compiler:2.45'
implementation("androidx.hilt:hilt-navigation-fragment:1.0.0")
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
// Testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
//Amplitude
implementation 'com.amplitude:android-sdk:3.35.1'
// Firestore
implementation platform('com.google.firebase:firebase-bom:31.4.0')
//Firebase UI
implementation 'com.firebaseui:firebase-ui:8.0.0'
//Konfetti UI Github Library
implementation 'nl.dionsegijn:konfetti:1.3.2'
// WhatTheStack
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
}
repositories {
mavenCentral()
}
Upvotes: 15
Views: 10098
Reputation: 3708
R8 breaks the older version of Retrofit library. This issue is fixed in the latest versions.
Try updating the retrofit library to 2.10.0 or higher
implementation 'com.squareup.retrofit2:retrofit:2.10.0'
In addition to this, add response-type-keeper
to generate keep rules
kapt 'com.squareup.retrofit2:response-type-keeper:2.10.0'
Upvotes: 0
Reputation: 219
Use this proguard rule
# Retrofit
-keep class retrofit2.** { *; }
# OkHttp
-keep class okhttp3.** { *; }
# Gson
-keep class com.google.gson.** { *; }
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
Upvotes: 1
Reputation: 1469
New proguard rules added but not published yet, you can add these rules to your proguard-rules files.
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
Upvotes: 7
Reputation: 6703
You haven't provided the code for your retrofit interface. So I will assume that you have declared some json data classes and use them in return type of your retrofit methods.
According to R8 FAQ the model data classes used as return type need to be kept as well:
example from the link:
interface Api {
@GET("<uri>")
fun getData(): Observable<Data>
}
Note, the Data class probably also needs to be kept if used since this is also constructed reflectively.
After reading this I added this rule to my proguard file and it worked:
-keep class my.app.packagename.api.response.** { <fields>; }
Note: my.app.packagename.api.response is the folder where I've added all Data classes I use as json models. For example:
package imy.app.packagename.api.response
import com.google.gson.annotations.SerializedName
data class AuthLoginJson(
@SerializedName("access_token") val accessToken: String? = null
)
Upvotes: 2
Reputation: 826
I faced the same problem. I found a solution that works for me. In the kotlin data class, I had some properties without a default value, like:
val name: String,
val city: String?,
This works without a problem with fullMode=false
, but with fullMode=true
I get a ClassCastException on Retrofit download.
Fix:
val name: String = "",
val city: String? = null,
Unfortunately, I don't understand why this is working.
Upvotes: 1
Reputation: 3242
Hi @Abhishek I Was facing the same issue while upgrading the android gradle plugin version to 8.0
I have solved it by adding some proguard-rules which you can find from
It works for me. I have explained it fully.
Upvotes: 1