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 with R8 full mode enabled with generics and Rx #3774

Closed
danielesegato opened this issue Sep 22, 2022 · 13 comments
Closed

Crash with R8 full mode enabled with generics and Rx #3774

danielesegato opened this issue Sep 22, 2022 · 13 comments

Comments

@danielesegato
Copy link

Retrofit: 2.9.0

The crashing retrofit interface contains methods like these:

    @FormUrlEncoded
    @POST("token/oauth2")
    fun clientCredentials(
        @Field("client_id") clientId: String,
        @Field("client_secret") clientSecret: String,
        @Field("grant_type") @SupportedGrantType grantType: String = SupportedGrantType.CLIENT_CREDENTIALS
    ): Single<Response<JWTEnvelope>>

where JWTEnvelope is my own class:

@Keep // androidx.annotation
@JsonClass(generateAdapter = true)
data class JWTEnvelope(
    @Json(name = "access_token")
    val accessToken: String,
    @Json(name = "token_type")
    @SupportedTokenType
    val tokenType: String,
    @Json(name = "expires_in")
    val expiresIn: Int,
    @Json(name = "refresh_token")
    val refreshToken: String? = null
)

I'm not sure if this is the same thing that is being discussed here #3588.
But I have the @Keep annotation so this should work if the issue is the one described there, isn't it?

I get

java.lang.RuntimeException: Unable to start activity ComponentInfo{my.app/my.app.home.HomeActivity}: java.lang.IllegalArgumentException: Unable to create call adapter for class lj.u
[...]
Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for class lj.u
    for method j.a
	at retrofit2.Utils.methodError(Utils.java:54)
	at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:116)
	at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:67)
	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 $Proxy5.a(Unknown Source)
	at my.app.auth.oauth2.OAuth2RestAPI$DefaultImpls.clientCredentials$default(OAuth2RestAPI.kt:18)
[...]
Caused by: java.lang.IllegalStateException: Single return type must be parameterized as Single<Foo> or Single<? extends Foo>
	at retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.get(RxJava2CallAdapterFactory.java:118)
	at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:253)
	at retrofit2.Retrofit.callAdapter(Retrofit.java:237)
	at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)
	... 81 more

The Single class is the one that can't be mapped apparently: io.reactivex.Single -> lj.u.

Am I supposed to just keep every Single class? or is there a better way?

Thanks

@vibin
Copy link
Contributor

vibin commented Oct 31, 2022

2.10.0-SNAPSHOT contains the fix you're looking for. Working fine for me with R8 full mode.

@Goooler
Copy link
Contributor

Goooler commented Nov 10, 2022

See #3751 (comment)

@danielesegato
Copy link
Author

Thank you!, both of you :)

@vibin
Copy link
Contributor

vibin commented Nov 11, 2022

UPDATE: The issue seems to be in AGP 7.2.2, not Retrofit. I have tried AGP 7.2 and 7.3 and both seem to be working fine with Retrofit with R8 full mode.


Actually, this has started reoccurring in my case after I upgraded AGP from 7.0.4 to 7.2.2. Looks like 2.10.0-SNAPSHOT is missing a rule or two...

 Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for interface retrofit2.Call
     for method HttpBinService.get
     at retrofit2.Utils.methodError(Utils.java:55)
     at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:116)
     at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:67)
     at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
     at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:208)
     at retrofit2.Retrofit$1.invoke(Retrofit.java:166)
     at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
     at $Proxy3.get(Unknown Source)
     at io.vibin.myapplication.MainActivity.onCreate(MainActivity.kt:45)
     at android.app.Activity.performCreate(Activity.java:8290)
     at android.app.Activity.performCreate(Activity.java:8269)
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
     ... 12 more
 Caused by: java.lang.IllegalArgumentException: Call return type must be parameterized as Call<Foo> or Call<? extends Foo>
     at retrofit2.DefaultCallAdapterFactory.get(DefaultCallAdapterFactory.java:42)
     at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:259)
     at retrofit2.Retrofit.callAdapter(Retrofit.java:243)
     at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)
     ... 23 more

@dbeltram
Copy link

I have added the rules to proguard and also followed these, but even with AGP8 and R8 enabled with retrofit 2.9.0:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'

I get the following:

Caused by: java.lang.IllegalStateException: Observable return type must be parameterized as Observable<Foo> or Observable<? extends Foo>
at retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory.get(RxJava3CallAdapterFactory.java:123)
at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:253)
at retrofit2.Retrofit.callAdapter(Retrofit.java:237)
at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)

I have been fighting with this issue for quite a while and I would like to re-enable the code shrinking: can anyone help?

@Goooler
Copy link
Contributor

Goooler commented Apr 27, 2023

# Keep generic signature of RxJava3 (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Flowable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Maybe
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Observable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Single

@dbeltram
Copy link

@Goooler Appreciated! Thanks!

@JakeWharton
Copy link
Collaborator

See #3886 which fixes this in a general way rather than us playing whack-a-mole in each adapter jar.

@tvaknin
Copy link

tvaknin commented May 12, 2023

# Keep generic signature of RxJava3 (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Flowable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Maybe
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Observable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Single

-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Flowable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Maybe
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Observable
-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Single

Thanks, but after adding this I got an error in response:
"Unable to create instance of class m.b. Registering an InstanceCreator or a TypeAdapter for this type, or adding a no-args constructor may fix this problem."

with minify disabled I have no errors.

@JakeWharton
Copy link
Collaborator

That's Gson, not Retrofit.

@equeim
Copy link

equeim commented Jul 4, 2023

See #3886 which fixes this in a general way rather than us playing whack-a-mole in each adapter jar.

With AGP 8.0.2 this works with Response<T> but not with Observable<Response<T>>:

java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Observable<retrofit2.Response>
Caused by: java.lang.IllegalStateException: Response must be parameterized as Response<Foo> or Response<? extends Foo>

@equeim
Copy link

equeim commented Jul 6, 2023

@JakeWharton #3910 fixes issue with Observable<Response<T>>.

@master255
Copy link

It helped me:
-keep,allowobfuscation,allowshrinking class io.reactivex.Flowable -keep,allowobfuscation,allowshrinking class io.reactivex.Maybe -keep,allowobfuscation,allowshrinking class io.reactivex.Observable -keep,allowobfuscation,allowshrinking class io.reactivex.Single

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

8 participants