Can I use them in Java code to take advantage of kotlin’s coroutines?
What is my goal?
My goal is to be able to use kotlin's coroutine system in Java I want to be able to pause execution for a given period of time and then back up at that location after a given period of time Starting from Java, I want to be able to execute tasks that are allowed to be suspended, rather than executing them asynchronously, for example:
//example 1 someLogic(); pause(3000L); //3 seconds someMoreLogic(); //example 2 while(true) { someContinuedLogic(); pause(10000L); //10 seconds }
What's my problem?
As expected, I was able to execute the co program completely from kotlin, but when it comes to Java, it becomes tricky because the Java part of the code immediately executes the whole block without any pause, and the kotlin block correctly pauses for 1 and then 4 seconds
What's my problem?
Can you even use kotlin as the backbone of Java collaboration? If so, what did I do wrong? Below you can find the source code to show how I try to use kotlin's collaborative program in Java
Ktscript class
abstract class KtScript { abstract fun execute() fun <T> async(block: suspend () -> T): CompletableFuture<T> { val future = CompletableFuture<T>() block.startCoroutine(completion = object : Continuation<T> { override fun resume(value: T) { future.complete(value) } override fun resumeWithException(exception: Throwable) { future.completeExceptionally(exception) } }) return future } suspend fun <T> await(f: CompletableFuture<T>): T = suspendCoroutine { c: Continuation<T> -> f.whenComplete { result,exception -> if (exception == null) c.resume(result) else c.resumeWithException(exception) } } fun pause(ms: Long): CompletableFuture<*> { //todo - a better pausing system (this is just temporary!) return CompletableFuture.runAsync { val currentMs = System.currentTimeMillis() while (System.currentTimeMillis() - currentMs < ms) { /* do nothing */ } } } }
Kotlin execution code
fun main(args: Array<String>) { ScriptTestKotlin().execute() } class ScriptTestKotlin : KtScript() { override fun execute() { println("Executing Kotlin script from Kotlin...") val future = async { await(pause(1000L)) println(" 1 second passed...") await(pause(4000L)) println(" 5 seconds passed...") } future.get() //wait for asynchronous task to finish println("Finished!") } }
Kotlin execution results
Executing Kotlin script from Kotlin... 1 second passed... 5 seconds passed... Finished!
Java execution code
public class ScriptTestJava extends KtScript { public static void main(String[] args) { new ScriptTestJava().execute(); } @Override public void execute() { System.out.println("Executing Kotlin script from Java..."); CompletableFuture<?> future = async(continuation -> { await(pause(1000L),continuation); System.out.println(" 1 second passed..."); await(pause(4000L),continuation); System.out.println(" 5 seconds passed..."); return continuation; }); try { future.get(); //wait for asynchronous task to finish } catch(Exception e) { e.printStackTrace(); } System.out.println("Finished!"); } }
Java execution results
Executing Kotlin script from Java... 1 second passed... 5 seconds passed... Finished!
^^^Unfortunately, pauses are skipped in Java^^^
Solution
Kotlin coroutine is realized through compiler conversion of code, which can only be completed by kotlinc
So, no, Java cannot use kotlin's collaboration mechanism because it is a compile time function