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
java.lang.ClassCastException when using @Retryable with coroutine #4438
Comments
@xiscosc I think I have a handle on the first problem, but the second is more difficult. We need to instrument the coroutine that gets passed to the method call in order to be aware of when it completes either successfully or in error. Currently we do that by providing a custom implementation of Coroutine that has our logic in it and delegates to the original. The issue here is that Kotlin is expecting the coroutine to implement CoroutineStackFrame which is an internal class. That means we can't simply implement the interface |
Maybe the solution would be to implement |
Hey @jameskleeh, I created a PR for a possible fix of the first problem |
@xiscosc I suggest you report |
@dstepanov Note that 2) is easily reproducible when you enable the coroutine debugger in IDEA Preferences | Build, Execution, Deployment | Debugger | Data Views | Kotlin If you do that, you will get those classcast exceptions when running micronaut (eg also happens in suspended controllers) |
@timducheyne I managed to reproduce it but I think the problem is not in Micronaut but in Kotlin's coroutine implementation which shouldn't blindly cast coroutines to the internal class. |
Yes that is indeed not nice. |
@timducheyne I went ahead and created the issue, I hope you don't mind. @jameskleeh and I think we have a handle on what the proper solve would be so I will be working on a PR to the coroutines library this afternoon |
@willbuck no I don't mind at all. Go ahead. I guess the fix is just use as? instead of as. |
@jameskleeh and I discussed that approach @timducheyne but I believe |
You're right. Implementing that internal interface is not the way to go. |
@Retryable
annotation is not working well with Kotlin coroutines. It does its work when some error is thrown but it fails when it's trying to return the correct value. I found two kind of errors:java.lang.IllegalStateException: Not a Kotlin coroutine
java.lang.ClassCastException: class io.micronaut.aop.util.CompletableFutureContinuation cannot be cast to class kotlin.coroutines.jvm.internal.CoroutineStackFrame (io.micronaut.aop.util.CompletableFutureContinuation and kotlin.coroutines.jvm.internal.CoroutineStackFrame are in unnamed module of loader 'app')
I created a project with several tests in order to reproduce them, it can be found here https://github.com/xiscosc/micronaut-kotlin-retry-coroutines
Steps to Reproduce
Not a Kotlin coroutine error
@Retryable
and a method that returns from a coroutineCast error
@Retryable
and a method that returns from a coroutine with a delayExpected Behaviour
Method
test2()
should return string"hi"
Actual Behaviour
Not a Kotlin coroutine error
Cast error
Environment Information
Example Application
The text was updated successfully, but these errors were encountered: