Reputation: 12454
I am trying to test Coroutine in Kotlin console project in IntellJ. I have added this library: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.0. It worked, until I used Dispatchers.Main
. After adding it, it threw a runtime exception.
import kotlinx.coroutines.*
val scope = CoroutineScope(Dispatchers.Main);
fun main(args: Array<String>) {
scope.launch { }
}
java.lang.IllegalStateException: Module with the Main dispatcher is missing. Add dependency providing the Main dispatcher, e.g. 'kotlinx-coroutines-android' and ensure it has the same version as 'kotlinx-coroutines-core'
I switched the library with org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0
as existing answer suggested, but then it threw a different runtime error.
NoClassDefFoundError: android/os/Looper
Seems like that the library is for Android. Is using 'kotlinx-coroutines-android' the correct solution for Kotlin console project? If not, how do I fix the problem?
Upvotes: 12
Views: 4864
Reputation: 37660
Dispatchers.Main
is most likely not what you want here. It is intended to dispatch coroutines on the main event loop in GUI applications.
For console applications, and especially in the kind of snippet you're sharing here, you probably instead want to use the main thread (in which main()
in executed) as the event loop, and prevent main()
from returning until coroutines are done. This is done by using runBlocking
, which blocks the current thread for outside code, but uses it as an event loop for the CoroutineScope
passed as this
to the lambda that you pass to runBlocking
.
So your code should likely look like:
import kotlinx.coroutines.*
fun main() {
runBlocking { // this: CoroutineScope
// there is a CoroutineScope here, the receiver is implicit
launch {
// this code will run in the main thread,
// concurrently with other coroutines and other code
// in the runBlocking lambda
}
// this code will run in the main thread,
// concurrently with the launch and other coroutines
}
}
If you did have a GUI application, you could check the KDoc for Dispatchers.Main to see which dispatcher is used depending on your target platform. If you target the JVM, you will need an extra dependency to bring the dispatcher that corresponds to the UI technology you use. This is also described in the KDoc:
In order to work with the Main dispatcher on the JVM, the following artifact should be added to the project runtime dependencies:
kotlinx-coroutines-android
— for Android Main thread dispatcher
kotlinx-coroutines-javafx
— for JavaFx Application thread dispatcher
kotlinx-coroutines-swing
— for Swing EDT dispatcher
Upvotes: 4
Reputation: 23
Import kotlinx-coroutines-swing:(your kotlin using version) in your dependencies gradle and compile the program
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-swing:$kotlin_coroutines_version"
Upvotes: 0
Reputation: 30595
Dispatchers.Main
is intended for GUI applications, it is not supported for the console project.
As per Guide to UI programming with coroutines kotlinx.coroutines has three modules that provide coroutine context for different UI application libraries:
Use runBlocking
to suspend main
function until coroutines are executed:
fun main(args: Array<String>) = runBlocking { ... }
Upvotes: 4