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

AWS Kotlin not compatible with the latest Kotlin release (1.7.0-RC2) #622

Closed
efemoney opened this issue Jun 2, 2022 · 4 comments · Fixed by #642
Closed

AWS Kotlin not compatible with the latest Kotlin release (1.7.0-RC2) #622

efemoney opened this issue Jun 2, 2022 · 4 comments · Fixed by #642
Assignees
Labels
bug This issue is a bug.

Comments

@efemoney
Copy link

efemoney commented Jun 2, 2022

Describe the bug

Exception after upgrading Kotlin (1.7.0-RC2) on first usage of AWS APIs, in this case, DynamoDbClient.query(...)

Expected behavior

AWS Kotlin should not crash / throw an exception.

Current behavior

Throws java.lang.IncompatibleClassChangeError: Found interface kotlin.time.TimeMark, but class was expected.

Stack trace

  org.springframework.web.util.NestedServletException: Async processing failed; nested exception is java.lang.IncompatibleClassChangeError: Found interface kotlin.time.TimeMark, but class was expected
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod$ConcurrentResultHandlerMethod.lambda$new$0(ServletInvocableHandlerMethod.java:223)
      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.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.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter.doFilter(TracingFilter.java:68)
      at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.doFilter(TraceWebServletConfiguration.java:131)
      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.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102)
      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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711)
      at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:632)
      at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:600)
      at org.apache.catalina.core.AsyncContextImpl$AsyncRunnable.run(AsyncContextImpl.java:587)
      at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:353)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:194)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
      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.springframework.cloud.sleuth.instrument.web.tomcat.TraceValve.invoke(TraceValve.java:85)
      at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:250)
      at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:241)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59)
      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)
  Caused by: java.lang.IncompatibleClassChangeError: Found interface kotlin.time.TimeMark, but class was expected
      at aws.smithy.kotlin.runtime.http.operation.SerializeHandler.call(SdkOperationExecution.kt:211)
      at aws.smithy.kotlin.runtime.http.operation.SerializeHandler.call(SdkOperationExecution.kt:102)
      at aws.smithy.kotlin.runtime.http.operation.InitializeHandler.call(SdkOperationExecution.kt:99)
      at aws.smithy.kotlin.runtime.io.middleware.Phase.handle(Phase.kt:60)
      at aws.smithy.kotlin.runtime.io.middleware.DecoratedHandler.call(Middleware.kt:40)
      at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt.execute(SdkHttpOperation.kt:83)
      at aws.smithy.kotlin.runtime.http.operation.SdkHttpOperationKt.roundTrip(SdkHttpOperation.kt:66)
      at aws.sdk.kotlin.services.dynamodb.DefaultDynamoDbClient.query(DefaultDynamoDbClient.kt:1254)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$queryPaginated$1.invokeSuspend(Paginators.kt:179)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$queryPaginated$1.invoke(Paginators.kt)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$queryPaginated$1.invoke(Paginators.kt)
      at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61)
      at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:230)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$items$$inlined$transform$1.invokeSuspend(Emitters.kt:40)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$items$$inlined$transform$1.invoke(Emitters.kt)
      at aws.sdk.kotlin.services.dynamodb.paginators.PaginatorsKt$items$$inlined$transform$1.invoke(Emitters.kt)
      at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61)
      at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:230)
      at com.careem.subscription.mobile.touchpoints.events.TouchPointDismissEventsRepository$allDismissEventsOf-fiY6rQs$suspendImpl$$inlined$map$1.collect(SafeCollector.common.kt:113)
      at kotlinx.coroutines.flow.FlowKt__CollectionKt.toCollection(Collection.kt:26)
      at kotlinx.coroutines.flow.FlowKt.toCollection(Unknown Source)
      at kotlinx.coroutines.flow.FlowKt__CollectionKt.toList(Collection.kt:15)
      at kotlinx.coroutines.flow.FlowKt.toList(Unknown Source)
      at kotlinx.coroutines.flow.FlowKt__CollectionKt.toList$default(Collection.kt:15)
      at kotlinx.coroutines.flow.FlowKt.toList$default(Unknown Source)
      at com.careem.subscription.mobile.touchpoints.events.TouchPointDismissEventsRepository.allDismissEventsOf-fiY6rQs$suspendImpl(store.kt:44)
      at com.careem.subscription.mobile.touchpoints.events.TouchPointDismissEventsRepository.allDismissEventsOf-fiY6rQs(store.kt)
      at com.careem.subscription.mobile.touchpoints.events.DefaultTouchPointDismissHandler.touchPointDismissVisibility-fiY6rQs$suspendImpl(handler.kt:41)
      at com.careem.subscription.mobile.touchpoints.events.DefaultTouchPointDismissHandler.touchPointDismissVisibility-fiY6rQs(handler.kt)
      at com.careem.subscription.mobile.touchpoints.TouchPointsController.mainTouchPoint$suspendImpl(TouchPointsController.kt:61)
      at com.careem.subscription.mobile.touchpoints.TouchPointsController.mainTouchPoint(TouchPointsController.kt)
      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 kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
      at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Instance.call(CallerImpl.kt:113)
      at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:108)
      at kotlin.reflect.full.KCallables.callSuspend(KCallables.kt:56)
      at org.springframework.core.CoroutinesUtils.lambda$invokeSuspendingFunction$2(CoroutinesUtils.java:79)
      at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$4.invokeSuspend(IntrinsicsJvm.kt:205)
      at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
      at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367)
      at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
      at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
      at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
      at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
      at kotlinx.coroutines.reactor.MonoKt.monoInternal$lambda-2(Mono.kt:90)
      at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:58)
      at reactor.core.publisher.Mono.subscribe(Mono.java:4400)
      at org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler$DeferredResultSubscriber.connect(ReactiveTypeHandler.java:451)
      at org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler.handleValue(ReactiveTypeHandler.java:166)
      at org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterReturnValueHandler.handleReturnValue(ResponseBodyEmitterReturnValueHandler.java:154)
      at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:135)
      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.cloud.sleuth.instrument.web.servlet.TracingFilter.doFilter(TracingFilter.java:68)
      at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.doFilter(TraceWebServletConfiguration.java:131)
      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 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.springframework.cloud.sleuth.instrument.web.tomcat.TraceValve.invoke(TraceValve.java:103)
      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)
      ... 7 more

Steps to Reproduce

Use latest Kotlin (1.7.0-RC2) with latest AWS Kotlin (0.16.0)

Possible Solution

Not sure what course of action to recommend here.

Context

For now I'm only trying to upgrade Kotlin to make sure our project will work with the upcoming 1.7 release.

I believe the the stdlib changed TimeMark from an abstract class to an interface but then again its marked as ExperimentalTime with AWS Kotlin opting into the experimental behavior.

measureTimedValue is the method being called and it, along with its chain of methods, get inlined at the call site. Seems binary compatibility of the compiled code is broken.

AWS Kotlin SDK version used

0.16.0

Platform (JVM/JS/Native)

Jvm (17)

Operating System and version

macOS Monterey 12.3.1

@efemoney efemoney added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jun 2, 2022
@aajtodd
Copy link
Contributor

aajtodd commented Jun 2, 2022

Thanks for reporting this.

Indeed it would appear TimeMark was an abstract class in 1.6.x and is an interface in 1.7.x which is a binary compatibility break.

The resolution on this one may end up just being support kotlin 1.7.x when available. That being said this is a good opportunity to comb our usage of any experimental APIs. I'll update here if we do anything earlier than supporting 1.7.x on this front.

@aajtodd aajtodd removed the needs-triage This issue or PR still needs to be triaged. label Jun 2, 2022
@efemoney
Copy link
Author

efemoney commented Jun 2, 2022

FTR, I dont see an issue with using experimental APIs (I actively encourage it!). Its just unfortunate that in this case Kotlin breaks ABI compatibility.

I have opened an issue with Kotlin here

@efemoney
Copy link
Author

efemoney commented Jun 9, 2022

The kotlin issue was updated. Summary is that the change is intentional & as designed.

I guess the fix here is to release a version compiled with 1.7.x (which is now released).

@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

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

Successfully merging a pull request may close this issue.

2 participants