Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when a release build is run in R8 full mode #647

Closed
mikescamell opened this issue Apr 13, 2023 · 8 comments
Closed

Crash when a release build is run in R8 full mode #647

mikescamell opened this issue Apr 13, 2023 · 8 comments

Comments

@mikescamell
Copy link

mikescamell commented Apr 13, 2023

Describe the problem

When running R8 in full mode (the upcoming default for Android Gradle Plugin 8) the app will crash on startup.

I believe that the SDK is missing some Proguard rules for Gson. See here.

What was the expected behavior?

No issues when running a release build with R8 full mode.

Reproduction

Run a release build with R8 full mode turned on

Caused by: 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.
    at com.google.gson.reflect.TypeToken.<init>(SourceFile:10)
    at com.auth0.android.request.internal.Jwt$mapAdapter$1.<init>(Unknown Source:0)
    at com.auth0.android.authentication.AuthenticationAPIClient.<init>(SourceFile:19)

Environment

  • v2.9.0
  • Gson
@poovamraj
Copy link
Contributor

Hi @mikescamell Thanks for reporting this!
I can see this recommendation in R8 FAQs as well - https://r8.googlesource.com/r8/+/refs/heads/master/compatibility-faq.md#troubleshooting-gson-gson

But I am not able to reproduce this issue so that I can verify if the solution works. Can you update this sample to reproduce this issue.

@mikescamell
Copy link
Author

mikescamell commented Apr 18, 2023

Hey @poovamraj thanks for getting back to me :)

I tried my best to recreate this in the sample this morning but no luck, I will try a bit more later.

But I can confirm that without these rules in our proguard file and R8 full mode on, the app will crash with the same exception.

# 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 

Seeing as R8 full mode is now the default in AGP 8 I imagine you might get more reports in future 😬

And it seems like you had a similar report here already

@poovamraj
Copy link
Contributor

@mikescamell can you share the snippet that you use that is causing the crash?

I totally agree that current configuration can lead to exception. I just want to understand fully about the issue before fixing it. Reaching out in the other thread as well.

@poovamraj
Copy link
Contributor

@mikescamell can you also ensure the project is using same Android Studio, AGP and other build tools with the same version as yours? You can share it here and I can check it out as well.

@mikescamell
Copy link
Author

@mikescamell can you also ensure the project is using same Android Studio, AGP and other build tools with the same version as yours? You can share it here and I can check it out as well.

We're using:

  • Android Studio Flamingo
  • AGP 8.0.0
  • JDK 17

I can reproduce it in the Blinkist app but not the Sample app you mentioned, which is kinda strange 🤔 Maybe our implementation using the Auth0 SDK is a bit more involved than the sample app, so R8 can strip the code out of the sample with no issues.

@poovamraj
Copy link
Contributor

Exactly, that's why I was wondering whether you could share your code snippet on how you use it.

@mikescamell
Copy link
Author

Exactly, that's why I was wondering whether you could share your code snippet on how you use it.

Ok here's our Service class that we use within the app.

class Auth0Service @AssistedInject constructor(
  @Assisted private val context: Context,
  @ApiEndpoint private val apiEndpoint: String,
) {

  interface Callback {

    fun onSuccess(email: String, accessToken: String)
    fun onFailure(code: String, description: String)
  }

  @AssistedFactory
  interface Factory {

    fun create(context: Context): Auth0Service
  }

  private val auth0Account = Auth0(context)

  private val authentication = AuthenticationAPIClient(auth0Account)
  private val storage = SharedPreferencesStorage(context)

  private val manager = CredentialsManager(authentication, storage)

  fun hasCredentials() = storage.retrieveString(ACCESS_TOKEN_KEY)?.isNotBlank() ?: false

  fun hasValidCredentials() =
    (storage.retrieveLong(EXPIRES_AT_KEY) ?: 0L) > System.currentTimeMillis()

  suspend fun getCredentials() =
    manager
      .awaitCredentials()
      .also { manager.saveCredentials(it) }
      .accessToken

  suspend fun login(): Auth0Credentials {
    val customTabsOptions = CustomTabsOptions.newBuilder().showTitle(true).build()

    val credentials =
      WebAuthProvider
        .login(auth0Account)
        .withScheme("blkauth")
        .withScope("openid email profile offline_access")
        .withAudience(apiEndpoint.removeSuffix("/"))
        .withCustomTabsOptions(customTabsOptions)
        .await(context)

    manager.saveCredentials(credentials)
    return Auth0Credentials(credentials.user.email!!, credentials.accessToken)
  }

  fun clearCredentials() {
    manager.clearCredentials()
  }
}

@poovamraj
Copy link
Contributor

Hi @mikescamell, we were not able to reproduce this but since it is recommended in the official documentation and wouldn't affect the functionality. We are going ahead with this.

Can you check out this PR and let us know if this fixes your issue - #652

We can follow up on the PR and we can close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants