apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.76k stars 653 forks source link

java.lang.NoSuchMethodError: 'kotlinx.coroutines.CoroutineDispatcher kotlinx.coroutines.rx3.RxSchedulerKt.asCoroutineDispatcher(io.reactivex.rxjava3.core.Scheduler)' #4300

Closed danielghandahari closed 2 years ago

danielghandahari commented 2 years ago

Summary

I'm migrating from Apollo Kotlin v2 to the latest v3 in my Java Spring Boot project. I'm getting a runtime error when executing my query with Rx3Apollo. The Rx3Apollo.single(queryCall) doesn't work for me.

Version

"com.apollographql.apollo3:apollo-api:3.4.0",
"com.apollographql.apollo3:apollo-rx3-support:3.4.0"

Logs

2022-07-28 11:06:47.634 ERROR 481593 [http-nio-8095-exec-1]  o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: 'kotlinx.coroutines.CoroutineDispatcher kotlinx.coroutines.rx3.RxSchedulerKt.asCoroutineDispatcher(io.reactivex.rxjava3.core.Scheduler)'] with root cause - line=676 nextStop=67043 finalStop=60050
java.lang.NoSuchMethodError: 'kotlinx.coroutines.CoroutineDispatcher kotlinx.coroutines.rx3.RxSchedulerKt.asCoroutineDispatcher(io.reactivex.rxjava3.core.Scheduler)'
    at com.apollographql.apollo3.rx3._Rx3ExtensionsKt.rxFlowable(-Rx3Extensions.kt:32)
    at com.apollographql.apollo3.rx3._Rx3ExtensionsKt.rxSingle(-Rx3Extensions.kt:26)
    at com.apollographql.apollo3.rx3.Rx3Apollo$Companion.single(Rx3Apollo.kt:34)
    at com.apollographql.apollo3.rx3.Rx3Apollo$Companion.single$default(Rx3Apollo.kt:33)
    at com.apollographql.apollo3.rx3.Rx3Apollo$Companion.single(Rx3Apollo.kt)
    at com.apollographql.apollo3.rx3.Rx3Apollo.single(Rx3Apollo.kt)
    at com.myproj.common.infrastructure.GraphqlWrapper.execute(GraphqlWrapper.java:32)
    at com.myproj.playlistservice.infrastructure.GraphqlSiteProvider.getSiteIdsByStopArea(GraphqlSiteProvider.java:23)
    at com.myproj.playlistservice.domain.PlaylistService.getContent(PlaylistService.java:61)
    at com.myproj.playlistservice.domain.PlaylistService.getPlaylist(PlaylistService.java:46)
    at com.myproj.playlistservice.controller.PlaylistController.getPlaylist(PlaylistController.java:37)
    at com.myproj.playlistservice.controller.PlaylistController$$FastClassBySpringCGLIB$$2aa18cb8.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
    at com.myproj.playlistservice.controller.PlaylistController$$EnhancerBySpringCGLIB$$e674d4dd.getPlaylist(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:833)

Steps to reproduce the behavior

I'm using a wrapper class to execute my query:

@Slf4j
@RequiredArgsConstructor
public class GraphqlWrapper {
  private final ApolloClient client;

  public <D extends Query.Data> D execute(Query<D> operation) {
    CompletableFuture<D> future = new CompletableFuture<>();

    ApolloCall queryCall = client.query(operation);
    Single<ApolloResponse<Operation.Data>> queryResponse = Rx3Apollo.single(queryCall);
    queryResponse.subscribe(
        apolloResponse -> {
          if (apolloResponse.hasErrors()) {
            apolloResponse.errors.forEach(e -> log.error(e.getMessage()));
          }
          future.complete((D) apolloResponse.data);
        },
        future::completeExceptionally);

    return Mono.fromFuture(future).block();
  }
}
BoD commented 2 years ago

Hi! 👋

We've had a similar issue in the past with SpringBoot where a different version of the coroutines library was found in the classpath, although we didn't really get to the bottom of the exact reason why.

Apollo Kotlin 3.4 depends on coroutines version 1.6.1. so I suppose that using 1.5.2 can be the cause of this issue (and we can see that the method in question has a different signature in 1.5.2 vs 1.6.1).

You could try to depend on a more recent version of SpringBoot (e.g. 2.7.2) which depends on a more recent version of coroutines / or try to pin coroutines on 1.6.1.

danielghandahari commented 2 years ago

Updating Spring Boot version solved it, thank you!