Tinder / Scarlet

A Retrofit inspired WebSocket client for Kotlin, Java, and Android
Other
3.24k stars 239 forks source link

Scarlet causing crash for no reason #155

Closed tapandesai closed 4 years ago

tapandesai commented 4 years ago

Here is the stacktrace

Caused by: java.lang.IllegalArgumentException: A method must have one and only one service method annotation: com.tinder.scarlet.internal.stub.StubMethod$Factory@f690cc7 at com.tinder.scarlet.internal.stub.StubMethod$Factory.create(StubMethod.kt:38) at com.tinder.scarlet.internal.stub.StubInterface$Factory.findStubMethods(StubInterface.kt:48) at com.tinder.scarlet.internal.stub.StubInterface$Factory.create(StubInterface.kt:42) at com.tinder.scarlet.Scarlet.create(Scarlet.kt:88) at com.careclues.channels.di.ChatModule.provideRocketChatWSApi(ChatModule.kt:118) at com.careclues.channels.di.ChatModule_ProvideRocketChatWSApiFactory.provideRocketChatWSApi(ChatModule_ProvideRocketChatWSApiFactory.java:35) at com.careclues.channels.DaggerCareCluesApplication_HiltComponents_ApplicationC.getRocketChatWSApi(DaggerCareCluesApplication_HiltComponents_ApplicationC.java:516) at com.careclues.channels.DaggerCareCluesApplication_HiltComponents_ApplicationC.getChatRepository(DaggerCareCluesApplication_HiltComponents_ApplicationC.java:615) at com.careclues.channels.DaggerCareCluesApplication_HiltComponents_ApplicationC.access$4600(DaggerCareCluesApplication_HiltComponents_ApplicationC.java:161) at com.careclues.channels.DaggerCareCluesApplication_HiltComponents_ApplicationC$SwitchingProvider.get(DaggerCareCluesApplication_HiltComponents_ApplicationC.java:1343) at com.careclues.channels.ui.login.LoginViewModel_AssistedFactory.create(LoginViewModel_AssistedFactory.java:33) at com.careclues.channels.ui.login.LoginViewModel_AssistedFactory.create(LoginViewModel_AssistedFactory.java:14) at androidx.hilt.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:76) at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54) at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41) at com.careclues.channels.ui.login.LoginActivity.getViewModel(Unknown Source:2) at com.careclues.channels.ui.login.LoginActivity.onCreate(LoginActivity.kt:47) at android.app.Activity.performCreate(Activity.java:7009) at android.app.Activity.performCreate(Activity.java:7000) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)  at android.app.ActivityThread.-wrap11(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6494)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Here is the interface. As you can see, all the methods are annotated properly. Can anyone please tell me what is the issue?

`interface RocketChatWSApi {

@Send
fun connect(connectMsg: ChatConnectMsg = ChatConnectMsg())

@Send
fun login(login: MethodCall<List<ChatLoginWSRequest>>)

@Send
fun loginWithToken(login: MethodCall<List<ChatTokenLoginWSRequest>>)

@Send
fun getRooms(getRoomsRequest: MethodCall<List<GetRoomsWSRequest>>)

@Send
fun markMessagesAsRead(markReadRequest: MethodCall<List<String>>)

@Send
fun subscribeToStream(request: SubscriptionCall)

@Send
fun sendMessage(sendMessageRequest: MethodCall<List<Any>>)

@Send
fun sendPong(pongMsg: PongMsg = PongMsg())

@Receive
fun receiveRocketChatMessages(): Flowable<RocketChatWSResponse>

@Receive
fun observeWebSocketEvent(): Flowable<WebSocketEvent>

}`

aaronweihe commented 4 years ago

did you have a function annotated with both @Send and @Receive or neither?

tapandesai commented 4 years ago

No. I have posted the interface over here. Only these methods are there and all of them are annotated properly

tapandesai commented 4 years ago

So incase someone is facing the same issue, this is how I fixed it

Replaced

@Send
fun connect(connectMsg: ChatConnectMsg = ChatConnectMsg())

with

@Send
fun connect(connectMsg: ChatConnectMsg)

Same for fun sendPong method. So somehow default values in parameter was causing the crash.

The only weird thing is same function with default value is working in another project.

radityagumay commented 3 years ago

This recently happening in our app for no reason, after digging on the rules and git bisect. we come to the conclusion to add these rules, and finally, we're able to address the issue

-if interface * { @com.tinder.scarlet.ws.* <methods>; }
-keep,allowobfuscation interface <1>

-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @com.tinder.scarlet.ws.* <methods>;
}
Screen Shot 2021-04-28 at 10 56 59
dazza5000 commented 2 years ago

What tool are you using to generate that visualization?

radityagumay commented 2 years ago

@dazza5000 proguard playground

MohammadFakhraee commented 6 months ago

Upgrading gradle version to 8.. version and enabling with minifyEnabled true, causes a weird crash!!

java.lang.IllegalArgumentException: Receive method must return ParameterizedType: public abstract kotlinx.coroutines.flow.Flow com.tinder.app.echo.api.EchoService.observeBitmap() at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:100)

@radityagumay Have you ever faced this issue? If yes how did you resolve?

The problem is when the demo is not minifying, the methods of scarlet service interfaces has a genericReturnType of ParameterizedTypeImpl type. But when switching minifyingEnabled on, the genericReturnType will become a type of java.lang.Class.

I know it is a very late question but I couldn't find anyone facing the same situation.

PanPersonalProject commented 4 months ago

Upgrading gradle version to 8.. version and enabling with minifyEnabled true, causes a weird crash!!

java.lang.IllegalArgumentException: Receive method must return ParameterizedType: public abstract kotlinx.coroutines.flow.Flow com.tinder.app.echo.api.EchoService.observeBitmap() at com.tinder.scarlet.internal.servicemethod.ServiceMethod$Receive$Factory.create(ServiceMethod.kt:100)

@radityagumay Have you ever faced this issue? If yes how did you resolve?

The problem is when the demo is not minifying, the methods of scarlet service interfaces has a genericReturnType of ParameterizedTypeImpl type. But when switching minifyingEnabled on, the genericReturnType will become a type of java.lang.Class.

I know it is a very late question but I couldn't find anyone facing the same situation.

keep rxjava solution