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

IllegalStateException when using coil-compose with Desktop Application #2184

Closed
seochanhee opened this issue Mar 27, 2024 · 3 comments
Closed

Comments

@seochanhee
Copy link

Hello,

I've encountered a runtime exception when using Coil with a desktop application that integrates JavaFX and Compose for Desktop. The exception only occurs in the desktop environment and not in common code or Android. The versions of Coil and related dependencies I'm using are as follows:

// Common dependencies
implementation("io.coil-kt.coil3:coil-compose:3.0.0-alpha06")
implementation("io.coil-kt.coil3:coil-compose-core:3.0.0-alpha06")
implementation("io.coil-kt.coil3:coil:3.0.0-alpha06")
implementation("io.coil-kt.coil3:coil-network-ktor:3.0.0-alpha06")

// Desktop-specific dependency
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.0")

The exception occurs on the JavaFX Application Thread and is related to the snapshot state management in Compose. Below is the stack trace of the exception:

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied
	at androidx.compose.runtime.snapshots.SnapshotKt.readError(Snapshot.kt:1929)
	at androidx.compose.runtime.snapshots.SnapshotKt.readable(Snapshot.kt:1913)
	at androidx.compose.runtime.SnapshotMutableStateImpl.getValue(SnapshotState.kt:135)
	at coil3.compose.AsyncImagePainter.getRequest(AsyncImagePainter.kt:433)
	at coil3.compose.AsyncImagePainter$onRemembered$1$1.invoke(AsyncImagePainter.kt:268)
	at coil3.compose.AsyncImagePainter$onRemembered$1$1.invoke(AsyncImagePainter.kt:268)
	at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invokeSuspend(SnapshotFlow.kt:181)
	at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invoke(SnapshotFlow.kt)
	at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1.invoke(SnapshotFlow.kt)
	at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:57)
	at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invokeSuspend(Merge.kt:23)
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Merge.kt)
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Merge.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61)
	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:261)
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest.flowCollect(Merge.kt:21)
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo$suspendImpl(ChannelFlow.kt:153)
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo(ChannelFlow.kt)
	at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun$1.invokeSuspend(ChannelFlow.kt:56)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.internal.DispatchedContinuation.resumeWith(DispatchedContinuation.kt:200)
	at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:129)
	at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:89)
	at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:123)
	at kotlinx.coroutines.channels.ProduceKt.produce(Produce.kt:129)
	at kotlinx.coroutines.channels.ProduceKt.produce$default(Produce.kt:117)
	at kotlinx.coroutines.flow.internal.ChannelFlow.produceImpl(ChannelFlow.kt:115)
	at kotlinx.coroutines.flow.internal.ChannelFlow$collect$2.invokeSuspend(ChannelFlow.kt:119)
	at kotlinx.coroutines.flow.internal.ChannelFlow$collect$2.invoke(ChannelFlow.kt)
	at kotlinx.coroutines.flow.internal.ChannelFlow$collect$2.invoke(ChannelFlow.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61)
	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:261)
	at kotlinx.coroutines.flow.internal.ChannelFlow.collect$suspendImpl(ChannelFlow.kt:118)
	at kotlinx.coroutines.flow.internal.ChannelFlow.collect(ChannelFlow.kt)
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collect$suspendImpl(ChannelFlow.kt:169)
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collect(ChannelFlow.kt)
	at coil3.compose.AsyncImagePainter$onRemembered$1.invokeSuspend(AsyncImagePainter.kt:270)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@41170662, Dispatchers.Main.immediate]

This error suggests an issue with reading a state that was created after a snapshot was taken or in a snapshot that has not yet been applied, occurring within coil3.compose.AsyncImagePainter.

I've confirmed that this issue only presents itself when running the desktop version of the application and does not occur in common or Android-specific code.

Could you please provide any guidance on how to resolve this issue? Is there a known workaround or fix that could be applied to ensure compatibility with desktop applications using JavaFX and Compose for Desktop?

Thank you for your support and the excellent library.

@colinrtwhite
Copy link
Member

This looks related to #1764. Unfortunately I haven't found a great way to solve this yet, but I'm thinking about it!

@seochanhee
Copy link
Author

@colinrtwhite Thanks! ^^

@colinrtwhite
Copy link
Member

Going to close this out to track in the main issue ticket.

@colinrtwhite colinrtwhite closed this as not planned Won't fix, can't repro, duplicate, stale Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants