kotlinx.coroutines
kotlinx.coroutines copied to clipboard
Fastloader breaks loading MainDispatcherFactory on Jvm Desktop
Describe the bug
FastLoader will fail in a way that loading the MainDispatcherFactory will appear missing despite being on the classpath.
Kotlin 1.9.20-rc Compose 1.5.10-beta02 Java 20 Coroutines 1.7.3
Provide a Reproducer
With fast loader on:
fun main() {
val factories = ServiceLoader.load(
MainDispatcherFactory::class.java,
MainDispatcherFactory::class.java.classLoader
).iterator().asSequence().toList()
println(factories)
val dispatcher = factories.maxByOrNull { it.loadPriority }?.tryCreateDispatcher(factories)
println(dispatcher)
println(Dispatchers.Main)
runBlocking(Dispatchers.Main) {
}
}
Log:
> Task :application:desktopApp:run
[kotlinx.coroutines.swing.SwingDispatcherFactory@f6c48ac]
Swing
Dispatchers.Main[missing]
Exception in thread "main" 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'
at kotlinx.coroutines.internal.MainDispatchersKt.throwMissingMainDispatcherException(MainDispatchers.kt:81)
at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.missing(MainDispatchers.kt:112)
at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.isDispatchNeeded(MainDispatchers.kt:96)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:319)
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.BuildersKt__BuildersKt.runBlocking(Builders.kt:58)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at co.....AppKt.main(App.kt:54)
at co.....AppKt.main(App.kt)
You set System.setProperty("kotlinx.coroutines.fast.service.loader", "false")
> Task :application:desktopApp:run
[kotlinx.coroutines.swing.SwingDispatcherFactory@f6c48ac]
Dispatchers.Main
Dispatchers.Main
This is a Multiplatfrom App by the way building a java application target, so I'm wondering if the classpath is slightly different? Happy try different things. But the work around is disabling fast loader for now which is fine
I could not reproduce this; for me, this code runs fine. Could you provide a complete project where this issue reproduces?
Interesting, I'll try to create a sample project
+1
System.setProperty("kotlinx.coroutines.fast.service.loader", "false")
This indeed helps. Thx
@alexzhirkevich same issue for you? What is your project setup? I'm trying to create a micro project to reproduce
@chrisjenx Do you have Gitlive/Firebase dependency in your project? It causes this issue. It brings firebase to java using android dependencies and some workarounds. Probably this dependencies have META-INF service with android main dispatcher factory which replaces swing one.
Here is small repro. But this probably not the coroutines issue
Yes I do. Interesting how that dep breaks it
On Sun, Nov 5, 2023 at 2:51 AM Alexander Zhirkevich < @.***> wrote:
@chrisjenx https://github.com/chrisjenx Do you have Gitlive/Firebase https://github.com/gitLiveApp/firebase-kotlin-sdk/ dependency in your project? It causes this issue. It brings firebase to java https://github.com/gitLiveApp/firebase-java-sdk using android dependencies and some workarounds. Probably this dependencies have META-INF service with android main dispatcher factory which replaces swing one.
Here is small repro https://github.com/alexzhirkevich/repro-coroutines-issue. But this probably not the coroutines issue
— Reply to this email directly, view it on GitHub https://github.com/Kotlin/kotlinx.coroutines/issues/3914#issuecomment-1793688775, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI5DMMSP2KHNUCGXXYECB3YC5OTJAVCNFSM6AAAAAA56SSN6OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTOOJTGY4DQNZXGU . You are receiving this because you were mentioned.Message ID: @.***>
I'm using Gitlive/Firebase dependency, too. The workaround that fixes this was disabling the service loader:
fun main() = application {
System.setProperty("kotlinx.coroutines.fast.service.loader", "false")
Window(onCloseRequest = ::exitApplication, title = "MyApp") {
MyApp()
}
}
@alexzhirkevich thank you for a self-contained reproducer!
I'm using Gitlive/Firebase dependency, too. The workaround that fixes this was disabling the service loader:
fun main() = application { System.setProperty("kotlinx.coroutines.fast.service.loader", "false") Window(onCloseRequest = ::exitApplication, title = "MyApp") { MyApp() } }
Interesting, as this ready happens inside the firebase-java-sdk: https://github.com/GitLiveApp/firebase-java-sdk/blob/abf1a6a628b205215d804f3052818121ffdd3558/src/main/java/com/google/firebase/FirebasePlatform.kt#L14
Interesting, as this ready happens inside the firebase-java-sdk:
Kotlin objects are lazy so this initialization probably performs way too late or doesn't perform at all
Kotlin objects are lazy so this initialization probably performs way too late or doesn't perform at all
Will always perform before any coroune usage in the sdk
https://github.com/GitLiveApp/firebase-java-sdk/tree/abf1a6a628b205215d804f3052818121ffdd3558?tab=readme-ov-file#initializing-the-sdk
@nbransby nice catch. I think it is not working because how the dependency of the Firebase (GitLive) library is injected in the code. For instance, later I noticed that I was getting the problem at the very beginning of the code startup (the same time the Firebase dependency was injected through a Service Locator). As @alexzhirkevich mentioned, it's like a race condition problem on how or when that line is invoked 🤔
Makes sense, glad there is a fix coming 👍