JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.24k stars 1.11k forks source link

How to use AndroidX ViewModels in Compose Desktop application? #4978

Closed Mikkareem closed 1 week ago

Mikkareem commented 1 week ago
class FooViewModel: ViewModel() {
       private fun fetchSomething() {
               viewModelScope.launch {
                      Repository.fetch()
               }
       }

       init { fetchSomething() }
}

@Composable
fun FooScreen() {
       val viewModel = viewModel<FooViewModel>()

      // Rest of the code
}

The dependencies I include,

import org.jetbrains.compose.desktop.application.dsl.TargetFormat

plugins {
    kotlin("jvm")
    id("org.jetbrains.compose")
    id("org.jetbrains.kotlin.plugin.compose")
    kotlin("plugin.serialization")
}

group = "com.examples"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    google()
}

dependencies {
    // Note, if you develop a library, you should use compose.desktop.common.
    // compose.desktop.currentOs should be used in launcher-sourceSet
    // (in a separate module for demo project and in testMain).
    // With compose.desktop.common you will also lose @Preview functionality
    implementation(compose.desktop.currentOs)
    implementation(compose.material3)

    val ktor = "2.3.11"
    implementation("io.ktor:ktor-client-core:$ktor")
    implementation("io.ktor:ktor-client-okhttp:$ktor")
    implementation("io.ktor:ktor-client-content-negotiation:$ktor")
    implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor")

    implementation("org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0")
}

compose.desktop {
    application {
        mainClass = "MainKt"

        nativeDistributions {
            targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "TempApp"
            packageVersion = "1.0.0"
        }
    }
}

The Runtime Exception which I get is,

Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Exception while trying to handle coroutine exception
    at kotlinx.coroutines.CoroutineExceptionHandlerKt.handlerException(CoroutineExceptionHandler.kt:33)
    at kotlinx.coroutines.internal.CoroutineExceptionHandlerImpl_commonKt.handleUncaughtCoroutineException(CoroutineExceptionHandlerImpl.common.kt:38)
    at kotlinx.coroutines.CoroutineExceptionHandlerKt.handleCoroutineException(CoroutineExceptionHandler.kt:24)
    at kotlinx.coroutines.StandaloneCoroutine.handleJobException(Builders.common.kt:190)
    at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:228)
    at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:907)
    at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:864)
    at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:829)
    at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:97)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$flush$1.invoke(FlushCoroutineDispatcher.skiko.kt:90)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$flush$1.invoke(FlushCoroutineDispatcher.skiko.kt:78)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.performRun(FlushCoroutineDispatcher.skiko.kt:99)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.flush(FlushCoroutineDispatcher.skiko.kt:78)
    at androidx.compose.ui.scene.ComposeSceneRecomposer.performScheduledEffects(ComposeSceneRecomposer.skiko.kt:91)
    at androidx.compose.ui.scene.BaseComposeScene.render(BaseComposeScene.skiko.kt:157)
    at androidx.compose.ui.scene.ComposeSceneMediator.onRender(ComposeSceneMediator.desktop.kt:537)
    at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:485)
    at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
    at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invokeSuspend(MetalRedrawer.kt:82)
    at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
    at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invoke(MetalRedrawer.kt)
    at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:33)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    Suppressed: java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
        at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.missing(MainDispatchers.kt:111)
        at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.isDispatchNeeded(MainDispatchers.kt:92)
        at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:315)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:21)
        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:88)
        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:123)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.async(Builders.common.kt:87)
        at kotlinx.coroutines.BuildersKt.async(Unknown Source)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.async$default(Builders.common.kt:78)
        at kotlinx.coroutines.BuildersKt.async$default(Unknown Source)
        at com.techullurgy.postmanclone.presentation.viewmodels.PostmanNewRestApiRequestViewModel.onSendClick(PostmanNewRestApiRequestViewModel.kt:43)
        at com.techullurgy.postmanclone.presentation.sections.PostmanNewRestApiRequestSectionKt$PostmanNewRestApiRequestSection$1$1$3.invoke(PostmanNewRestApiRequestSection.kt:48)
        at com.techullurgy.postmanclone.presentation.sections.PostmanNewRestApiRequestSectionKt$PostmanNewRestApiRequestSection$1$1$3.invoke(PostmanNewRestApiRequestSection.kt:48)
        at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:991)
        at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke(Clickable.kt:984)
        at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:258)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:164)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:470)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:504)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:493)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:364)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:672)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:549)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:571)
        at androidx.compose.foundation.AbstractClickablePointerInputNode.onPointerEvent-H0pRuoY(Clickable.kt:950)
        at androidx.compose.foundation.AbstractClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:798)
        at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:326)
        at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
        at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:187)
        at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:106)
        at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:114)
        at androidx.compose.ui.node.RootNodeOwner.onPointerInput(RootNodeOwner.skiko.kt:212)
        at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processRelease(MultiLayerComposeScene.skiko.kt:321)
        at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processPointerInputEvent(MultiLayerComposeScene.skiko.kt:236)
        at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:62)
        at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:62)
        at androidx.compose.ui.input.pointer.SyntheticEventSender.sendInternal(SyntheticEventSender.skiko.kt:175)
        at androidx.compose.ui.input.pointer.SyntheticEventSender.send(SyntheticEventSender.skiko.kt:79)
        at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-WlEVilQ(ComposeSceneInputHandler.skiko.kt:123)
        at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-BGSDPeU(ComposeSceneInputHandler.skiko.kt:89)
        at androidx.compose.ui.scene.BaseComposeScene.sendPointerEvent-BGSDPeU(BaseComposeScene.skiko.kt:185)
        at androidx.compose.ui.scene.ComposeScene.sendPointerEvent-BGSDPeU$default(ComposeScene.skiko.kt:186)
        at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:709)
        at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.access$onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:1)
        at androidx.compose.ui.scene.ComposeSceneMediator.onMouseEvent(ComposeSceneMediator.desktop.kt:403)
        at androidx.compose.ui.scene.ComposeSceneMediator.access$onMouseEvent(ComposeSceneMediator.desktop.kt:102)
        at androidx.compose.ui.scene.ComposeSceneMediator$mouseListener$1.mouseReleased(ComposeSceneMediator.desktop.kt:234)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
        at java.desktop/java.awt.Component.processEvent(Component.java:6391)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
        ... 6 more
    Caused by: java.lang.NoClassDefFoundError: android/os/Looper
        at kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:51)
        at kotlinx.coroutines.internal.MainDispatchersKt.tryCreateDispatcher(MainDispatchers.kt:53)
        at kotlinx.coroutines.internal.MainDispatcherLoader.loadMainDispatcher(MainDispatchers.kt:34)
        at kotlinx.coroutines.internal.MainDispatcherLoader.<clinit>(MainDispatchers.kt:18)
        at kotlinx.coroutines.Dispatchers.getMain(Dispatchers.kt:20)
        at androidx.lifecycle.MainDispatcherChecker.updateMainDispatcherThread(MainDispatcherChecker.desktop.kt:28)
        at androidx.lifecycle.MainDispatcherChecker.isMainDispatcherThread(MainDispatcherChecker.desktop.kt:56)
        at androidx.lifecycle.LifecycleRegistry_desktopKt.isMainThread(LifecycleRegistry.desktop.kt:20)
        at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.jvm.kt:302)
        at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.jvm.kt:106)
        at androidx.compose.ui.scene.ComposeContainer.updateLifecycleState(ComposeContainer.desktop.kt:453)
        at androidx.compose.ui.scene.ComposeContainer.onWindowFocusChanged(ComposeContainer.desktop.kt:222)
        at androidx.compose.ui.scene.ComposeContainer.setWindow(ComposeContainer.desktop.kt:314)
        at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:182)
        at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:82)
        at androidx.compose.ui.awt.ComposeWindowPanel.<init>(ComposeWindowPanel.desktop.kt:52)
        at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:65)
        at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:63)
        at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:182)
        at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:176)
        at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:409)
        at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:406)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:70)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:69)
        at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:82)
        at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1295)
        at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
        at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1005)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1099)
        at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
        at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:221)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
        ... 6 more
    Caused by: java.lang.ClassNotFoundException: android.os.Looper
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 47 more
Caused by: java.lang.NoClassDefFoundError: android/os/Build$VERSION
    at kotlinx.coroutines.android.AndroidExceptionPreHandler.handleException(AndroidExceptionPreHandler.kt:43)
    at kotlinx.coroutines.internal.CoroutineExceptionHandlerImpl_commonKt.handleUncaughtCoroutineException(CoroutineExceptionHandlerImpl.common.kt:34)
    ... 37 more
Caused by: java.lang.ClassNotFoundException: android.os.Build$VERSION
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 39 more
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
    at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.missing(MainDispatchers.kt:111)
    at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.isDispatchNeeded(MainDispatchers.kt:92)
    at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:315)
    at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
    at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:21)
    at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:88)
    at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:123)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.async(Builders.common.kt:87)
    at kotlinx.coroutines.BuildersKt.async(Unknown Source)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.async$default(Builders.common.kt:78)
    at kotlinx.coroutines.BuildersKt.async$default(Unknown Source)
    at com.techullurgy.postmanclone.presentation.viewmodels.PostmanNewRestApiRequestViewModel.onSendClick(PostmanNewRestApiRequestViewModel.kt:43)
    at com.techullurgy.postmanclone.presentation.sections.PostmanNewRestApiRequestSectionKt$PostmanNewRestApiRequestSection$1$1$3.invoke(PostmanNewRestApiRequestSection.kt:48)
    at com.techullurgy.postmanclone.presentation.sections.PostmanNewRestApiRequestSectionKt$PostmanNewRestApiRequestSection$1$1$3.invoke(PostmanNewRestApiRequestSection.kt:48)
    at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:991)
    at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke(Clickable.kt:984)
    at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:258)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
    at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:164)
    at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:470)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:504)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:493)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:364)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:672)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:549)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:571)
    at androidx.compose.foundation.AbstractClickablePointerInputNode.onPointerEvent-H0pRuoY(Clickable.kt:950)
    at androidx.compose.foundation.AbstractClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:798)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:326)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
    at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:187)
    at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:106)
    at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:114)
    at androidx.compose.ui.node.RootNodeOwner.onPointerInput(RootNodeOwner.skiko.kt:212)
    at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processRelease(MultiLayerComposeScene.skiko.kt:321)
    at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processPointerInputEvent(MultiLayerComposeScene.skiko.kt:236)
    at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:62)
    at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:62)
    at androidx.compose.ui.input.pointer.SyntheticEventSender.sendInternal(SyntheticEventSender.skiko.kt:175)
    at androidx.compose.ui.input.pointer.SyntheticEventSender.send(SyntheticEventSender.skiko.kt:79)
    at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-WlEVilQ(ComposeSceneInputHandler.skiko.kt:123)
    at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-BGSDPeU(ComposeSceneInputHandler.skiko.kt:89)
    at androidx.compose.ui.scene.BaseComposeScene.sendPointerEvent-BGSDPeU(BaseComposeScene.skiko.kt:185)
    at androidx.compose.ui.scene.ComposeScene.sendPointerEvent-BGSDPeU$default(ComposeScene.skiko.kt:186)
    at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:709)
    at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.access$onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:1)
    at androidx.compose.ui.scene.ComposeSceneMediator.onMouseEvent(ComposeSceneMediator.desktop.kt:403)
    at androidx.compose.ui.scene.ComposeSceneMediator.access$onMouseEvent(ComposeSceneMediator.desktop.kt:102)
    at androidx.compose.ui.scene.ComposeSceneMediator$mouseListener$1.mouseReleased(ComposeSceneMediator.desktop.kt:234)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.scene.ComposeContainer$DesktopCoroutineExceptionHandler@341b57a4, androidx.compose.runtime.BroadcastFrameClock@dd7b330, StandaloneCoroutine{Cancelling}@5ae16821, FlushCoroutineDispatcher@4d4f3312]
Caused by: java.lang.NoClassDefFoundError: android/os/Looper
    at kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:51)
    at kotlinx.coroutines.internal.MainDispatchersKt.tryCreateDispatcher(MainDispatchers.kt:53)
    at kotlinx.coroutines.internal.MainDispatcherLoader.loadMainDispatcher(MainDispatchers.kt:34)
    at kotlinx.coroutines.internal.MainDispatcherLoader.<clinit>(MainDispatchers.kt:18)
    at kotlinx.coroutines.Dispatchers.getMain(Dispatchers.kt:20)
    at androidx.lifecycle.MainDispatcherChecker.updateMainDispatcherThread(MainDispatcherChecker.desktop.kt:28)
    at androidx.lifecycle.MainDispatcherChecker.isMainDispatcherThread(MainDispatcherChecker.desktop.kt:56)
    at androidx.lifecycle.LifecycleRegistry_desktopKt.isMainThread(LifecycleRegistry.desktop.kt:20)
    at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.jvm.kt:302)
    at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.jvm.kt:106)
    at androidx.compose.ui.scene.ComposeContainer.updateLifecycleState(ComposeContainer.desktop.kt:453)
    at androidx.compose.ui.scene.ComposeContainer.onWindowFocusChanged(ComposeContainer.desktop.kt:222)
    at androidx.compose.ui.scene.ComposeContainer.setWindow(ComposeContainer.desktop.kt:314)
    at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:182)
    at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:82)
    at androidx.compose.ui.awt.ComposeWindowPanel.<init>(ComposeWindowPanel.desktop.kt:52)
    at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:65)
    at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:63)
    at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:182)
    at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:176)
    at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:409)
    at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:406)
    at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:70)
    at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:69)
    at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:82)
    at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1295)
    at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
    at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1005)
    at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1099)
    at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
    at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
    at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:221)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: android.os.Looper
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 47 more
apolostudio commented 1 week ago

i think you need -> implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.1") (check if this version is the latest)

MatkovIvan commented 1 week ago

You can find documentation here: https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-viewmodel.html

When running coroutines in a ViewModel, remember that the ViewModel.viewModelScope value is tied to the Dispatchers.Main.immediate value, which might be unavailable on desktop by default. To make ViewModel coroutines work correctly with Compose Multiplatform, add the kotlinx-coroutines-swing dependency to your project. See the Dispatchers.Main documentation for details.