kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Fastloader breaks loading MainDispatcherFactory on Jvm Desktop

Open chrisjenx opened this issue 2 years ago • 8 comments
trafficstars

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

chrisjenx avatar Oct 13 '23 05:10 chrisjenx

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

chrisjenx avatar Oct 13 '23 15:10 chrisjenx

I could not reproduce this; for me, this code runs fine. Could you provide a complete project where this issue reproduces?

dkhalanskyjb avatar Oct 16 '23 06:10 dkhalanskyjb

Interesting, I'll try to create a sample project

chrisjenx avatar Oct 16 '23 19:10 chrisjenx

+1

System.setProperty("kotlinx.coroutines.fast.service.loader", "false")

This indeed helps. Thx

alexzhirkevich avatar Nov 04 '23 22:11 alexzhirkevich

@alexzhirkevich same issue for you? What is your project setup? I'm trying to create a micro project to reproduce

chrisjenx avatar Nov 04 '23 23:11 chrisjenx

@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

alexzhirkevich avatar Nov 05 '23 09:11 alexzhirkevich

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: @.***>

chrisjenx avatar Nov 05 '23 15:11 chrisjenx

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()
    }
}

jflavio11 avatar Feb 11 '24 22:02 jflavio11

@alexzhirkevich thank you for a self-contained reproducer!

qwwdfsad avatar Apr 16 '24 15:04 qwwdfsad

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

nbransby avatar Apr 17 '24 03:04 nbransby

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

alexzhirkevich avatar Apr 17 '24 05:04 alexzhirkevich

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 avatar Apr 17 '24 06:04 nbransby

@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 🤔

jflavio11 avatar Apr 17 '24 16:04 jflavio11

Makes sense, glad there is a fix coming 👍

nbransby avatar Apr 17 '24 16:04 nbransby