Hey everyone, I'm using coroutines and trying to ...
# coroutines
m
Hey everyone, I'm using coroutines and trying to bridge some java-kotlin code. I landed on using
BuildersKt.launch()
. In my domain layer, we have some suspending functions.
Copy code
override suspend fun voidPayment(uid: String): Boolean
Right now, these suspending functions need to be called from java Activity/Fragment.
Copy code
Job voidJob = BuildersKt.launch(
                        GlobalScope.INSTANCE,
                        (CoroutineContext) Dispatchers.getIO(),
                        CoroutineStart.DEFAULT,
                        (scope, cont) -> {
                         outsideVariable.set(object.voidPayment(uid))
                            voidable.set(Boolean.parseBoolean(janePayProcessor.voidPayment(mOrder.total, mOrder.tuid, (Continuation<? super Boolean>) cont).toString()));
                            if (voidable.get())
                                actuallyProceedWithVoid();
                            return true;
                        });
The execution of the suspending function results in an internal coroutine error
Copy code
kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[Dispatchers.Default, Continuation at object.voidPayment(object.kt:64)@d43fc03]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
                                                                                                    	at kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx_coroutines_core(DispatchedTask.kt:146)
                                                                                                    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:117)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
                                                                                                    	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Completed}@4a17bac, Dispatchers.Default]
                                                                                                    Caused by: java.lang.ClassCastException: kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to kotlinx.coroutines.internal.DispatchedContinuation
Any insights on this?
f
I'd suggest that, instead of shoehorning coroutines into a Java class, consider creating a separate Kotlin class that handles these calls and then using that class in your Activity/Fragment instead (though ideally this should not be in the UI layer but in a viewmodel or similar, but that's a separate issue)
m
Yes that is a valid suggestion but for the purposes of this question I need to shorehorn this into java class
f
well, all I can say in that case is, good luck to you then
j
Using coroutine builders and suspend functions require transformations made by the Kotlin compiler. To my knowledge, it's not possible to use suspend functions from Java (or at least very annoying, and not via the usual Kotlin coroutine builders)
s
Not impossible, I think but this requires deep knowledge of the coroutine inner workings and unstable and error prone code. Instead write java friendly wrappers in Kotlin around your suspend functions, wrappers using plain callbacks or futures or reactive classes (you can write a bunch a new Kotlin classes that do just this, as an adapter), and call these in your java code instead.
176 Views