Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fastloader breaks loading MainDispatcherFactory on Jvm Desktop #3914

Closed
chrisjenx opened this issue Oct 13, 2023 · 14 comments
Closed

Fastloader breaks loading MainDispatcherFactory on Jvm Desktop #3914

chrisjenx opened this issue Oct 13, 2023 · 14 comments
Assignees
Labels

Comments

@chrisjenx
Copy link

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 chrisjenx added the bug label Oct 13, 2023
@chrisjenx
Copy link
Author

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

@dkhalanskyjb
Copy link
Collaborator

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

@chrisjenx
Copy link
Author

Interesting, I'll try to create a sample project

@alexzhirkevich
Copy link

+1

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

This indeed helps. Thx

@chrisjenx
Copy link
Author

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

@alexzhirkevich
Copy link

@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

@chrisjenx
Copy link
Author

chrisjenx commented Nov 5, 2023 via email

@qwwdfsad qwwdfsad self-assigned this Nov 30, 2023
@jflavio11
Copy link

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

qwwdfsad added a commit that referenced this issue Apr 16, 2024
For desktop applications, Swing/JavaFx dispatcher should be picked by our fast SL mechanism. But if there is a dependency on firebase-sdk, it breaks: the dependency repackages Android classes, and we incorrectly assume we are on Android platform.

Explicitly take it into account

Fixes #3914
@qwwdfsad
Copy link
Collaborator

@alexzhirkevich thank you for a self-contained reproducer!

@nbransby
Copy link

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

@alexzhirkevich
Copy link

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

@nbransby
Copy link

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

@jflavio11
Copy link

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

@nbransby
Copy link

Makes sense, glad there is a fix coming 👍

Corje pushed a commit that referenced this issue May 10, 2024
For desktop applications, Swing/JavaFx dispatcher should be picked by our fast SL mechanism. But if there is a dependency on firebase-sdk, it breaks: the dependency repackages Android classes, and we incorrectly assume we are on Android platform.

Explicitly take it into account

Fixes #3914
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants