Abhishek AN
Abhishek AN

Reputation: 808

R8 full mode throws class cast exception AGP 8.0

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

Answers (6)

Srikar Reddy
Srikar Reddy

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

Shubham Pandey
Shubham Pandey

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

M.Yogeshwaran
M.Yogeshwaran

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

Marat
Marat

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

Mario Huizinga
Mario Huizinga

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

Chirag Thummar
Chirag Thummar

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

Upgrading Gradle from 7.4.2 to Gradle 8.0.0 gives error on release app - java.lang.ClassCastException

It works for me. I have explained it fully.

Upvotes: 1

Related Questions