compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

Font transform has NaN Position crash

Open samuelprince77 opened this issue 2 years ago • 4 comments

I notice that occasionally my desktop application will crash on Mac if i leave it open for an extended amount of time idle (open but not in use). On rare occasions, it will crash while the application is in active use. In the kotlin slack channel someone mentioned that they experience the same thing and that it happens when there is no clipboard data and copying some text to the clip board fixes it. The application uses an OutlinedTextField and this is the stack trace:

Exception in thread "AWT-EventQueue-0" java.io.IOException: Font transform has NaN position at java.desktop/sun.lwawt.macosx.CClipboard.getClipboardData(Native Method) at java.desktop/sun.awt.datatransfer.SunClipboard.getData(SunClipboard.java:219) at org.jetbrains.skiko.Actuals_awtKt.ClipboardManager_getText(Actuals.awt.kt:62) at org.jetbrains.skiko.ClipboardManager.getText(Platform.kt:28) at androidx.compose.ui.platform.PlatformClipboardManager.getText(PlatformClipboardManager.skiko.kt:26) at androidx.compose.foundation.text.ContextMenu_desktopKt$contextMenuItems$1.invoke(ContextMenu.desktop.kt:93) at androidx.compose.foundation.text.ContextMenu_desktopKt$contextMenuItems$1.invoke(ContextMenu.desktop.kt:72) at androidx.compose.foundation.ContextMenuData$allItemsSeq$1.invokeSuspend(ContextMenuProvider.desktop.kt:184) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlin.sequences.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:140) at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:786) at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:816) at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:807) at androidx.compose.foundation.ContextMenuData$allItems$2.invoke(ContextMenuProvider.desktop.kt:179) at androidx.compose.foundation.ContextMenuData$allItems$2.invoke(ContextMenuProvider.desktop.kt:178) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at androidx.compose.foundation.ContextMenuData.getAllItems$foundation(ContextMenuProvider.desktop.kt:178) at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuArea$2.invoke(ContextMenuProvider.desktop.kt:61) at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuArea$2.invoke(ContextMenuProvider.desktop.kt:57) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuDataProvider$2.invoke(ContextMenuProvider.desktop.kt:94) at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuDataProvider$2.invoke(ContextMenuProvider.desktop.kt:93) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228) at androidx.compose.foundation.ContextMenuProvider_desktopKt.ContextMenuDataProvider(ContextMenuProvider.desktop.kt:91) at androidx.compose.foundation.ContextMenuProvider_desktopKt.ContextMenuArea(ContextMenuProvider.desktop.kt:57) at androidx.compose.foundation.text.ContextMenu_desktopKt.ContextMenuArea(ContextMenu.desktop.kt:43) at androidx.compose.foundation.text.CoreTextFieldKt.CoreTextFieldRootBox(CoreTextField.kt:604) at androidx.compose.foundation.text.CoreTextFieldKt.CoreTextField(CoreTextField.kt:521) at androidx.compose.foundation.text.BasicTextFieldKt.BasicTextField(BasicTextField.kt:275) at androidx.compose.material.OutlinedTextFieldKt.OutlinedTextField(OutlinedTextField.kt:304) at ApplicationKt.Application(Application.kt:164) at ApplicationKt$Application$2.invoke(Application.kt) at ApplicationKt$Application$2.invoke(Application.kt) at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:157) at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2320) at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2580) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3164) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3142) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:252) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source) at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3142) at androidx.compose.runtime.ComposerImpl.recompose$runtime(Composer.kt:3108) at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:724) at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:879) at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:110) at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:488) at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:457) at androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume(BroadcastFrameClock.kt:44) at androidx.compose.runtime.BroadcastFrameClock.sendFrame(BroadcastFrameClock.kt:73) at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:381) at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:236) at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:235) at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:88) at androidx.compose.ui.awt.ComposeLayer.access$catchExceptions(ComposeLayer.desktop.kt:68) at androidx.compose.ui.awt.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:235) at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:455) at org.jetbrains.skiko.redrawer.MetalRedrawer.update(MetalRedrawer.kt:66) at org.jetbrains.skiko.redrawer.MetalRedrawer.access$update(MetalRedrawer.kt:13) at org.jetbrains.skiko.redrawer.MetalRedrawer$frameDispatcher$1.invokeSuspend(MetalRedrawer.kt:38) 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:106) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740) 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) Warning: the fonts "Times" and "Times" are not available for the Java logical font "Serif", which may have unexpected appearance or behavior. Re-enable the "Times" font to remove this warning.

samuelprince77 avatar Jun 05 '22 17:06 samuelprince77

Happens in my app when it Crossfades to a state/screen containing an OutlinedTextField. It either happens immediately or it doesn't crash, no need for it to be idle on my end.

compose-jb 1.2.0-alpha01-dev686 macos 12.3.1

asapha avatar Jun 05 '22 22:06 asapha

@asapha Do you have a consistent minimal repro of the bug? Hard to fix+verify with just a stack trace, would be great to get a consistent minimal repro attached to this bug.

@igordmn One of our engineers within Google recently reported the same intermittent issue with their internal CFD app.

@igordmn It looks like the root cause might be within Skiko since https://youtrack.jetbrains.com/issue/FL-12239 appears to have the same root cause (uses skiko called by noria):

  Caused by: java.io.IOException: Font transform has NaN position  at [email protected]/sun.lwawt.macosx.CClipboard.getClipboardData(Native Method)
  at [email protected]/sun.awt.datatransfer.ClipboardTransferable.fetchOneFlavor(Unknown Source)
  at [email protected]/sun.awt.datatransfer.ClipboardTransferable.lambda$new$0(Unknown Source)
  at [email protected]/java.util.HashMap$EntrySet.forEach(Unknown Source)
  at [email protected]/sun.awt.datatransfer.ClipboardTransferable.<init>(Unknown Source)
  at [email protected]/sun.awt.datatransfer.SunClipboard.getContents(Unknown Source)
  at [email protected]/sun.lwawt.macosx.CClipboard.getContents(Unknown Source)
  at fleet.noria.kwinit/noria.kwinit.impl.skiko.ClipboardImpl.getContent(ClipboardImpl.kt:62)
  at fleet.noria.kwinit/noria.kwinit.ClipboardKt.getText(Clipboard.kt:47)
  at fleet.frontend.ui/fleet.frontend.ui.editor.CopyBufferPopupViewKt$pasteFromHistory$1$1$2.invoke(CopyBufferPopupView.kt:128)
  at fleet.frontend.ui/fleet.frontend.ui.editor.CopyBufferPopupViewKt$pasteFromHistory$1$1$2.invoke(CopyBufferPopupView.kt:123)
  at fleet.frontend/fleet.frontend.actions.FleetActionsKt$Action$1$1.invoke(FleetActions.kt:79)
  at fleet.frontend/fleet.frontend.actions.FleetActionsKt$Action$1$1.invoke(FleetActions.kt:78)

jimgoog avatar Aug 24 '22 18:08 jimgoog

It seems to happen when the clipboard is busy, as the equivalent error message in Windows is cannot open system clipboard.

To repro:

  1. Run this code in another program
fun main(args: Array<String>) {
    while (true) {
        try {
            Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection("hello"), null)
            Thread.sleep(1)
        } catch (e: Exception) {
            println(e.message)
        }
    }
}
  1. In your Compose app, try to select some text

The app should crash when trying to access the clipboard, in Windows and in macOS.

It seems like jetbrains/skiko#579 will catch the IOException thrown in macOS but not the IllegalStateException thrown in Windows.

(modifying the clipboard is also affected, see #2270)

Stacktrace from Windows:

java.lang.IllegalStateException: cannot open system clipboard
	at java.desktop/sun.awt.windows.WClipboard.openClipboard(Native Method)
	at java.desktop/sun.awt.datatransfer.SunClipboard.getData(SunClipboard.java:208)
	at org.jetbrains.skiko.Actuals_awtKt.ClipboardManager_getText(Actuals.awt.kt:60)
	at org.jetbrains.skiko.ClipboardManager.getText(Platform.kt:28)
	at androidx.compose.ui.platform.PlatformClipboardManager.getText(PlatformClipboardManager.skiko.kt:26)
	at androidx.compose.foundation.text.ContextMenu_desktopKt$contextMenuItems$1.invoke(ContextMenu.desktop.kt:93)
	at androidx.compose.foundation.text.ContextMenu_desktopKt$contextMenuItems$1.invoke(ContextMenu.desktop.kt:72)
	at androidx.compose.foundation.ContextMenuData$allItemsSeq$1.invokeSuspend(ContextMenuProvider.desktop.kt:184)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlin.sequences.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:127)
	at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:787)
	at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:817)
	at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:808)
	at androidx.compose.foundation.ContextMenuData$allItems$2.invoke(ContextMenuProvider.desktop.kt:179)
	at androidx.compose.foundation.ContextMenuData$allItems$2.invoke(ContextMenuProvider.desktop.kt:178)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at androidx.compose.foundation.ContextMenuData.getAllItems$foundation(ContextMenuProvider.desktop.kt:178)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuArea$2.invoke(ContextMenuProvider.desktop.kt:61)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuArea$2.invoke(ContextMenuProvider.desktop.kt:57)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuDataProvider$2.invoke(ContextMenuProvider.desktop.kt:94)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt$ContextMenuDataProvider$2.invoke(ContextMenuProvider.desktop.kt:93)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt.ContextMenuDataProvider(ContextMenuProvider.desktop.kt:91)
	at androidx.compose.foundation.ContextMenuProvider_desktopKt.ContextMenuArea(ContextMenuProvider.desktop.kt:57)
	at androidx.compose.foundation.text.ContextMenu_desktopKt.ContextMenuArea(ContextMenu.desktop.kt:43)
	at androidx.compose.foundation.text.CoreTextFieldKt.CoreTextFieldRootBox(CoreTextField.kt:618)
	at androidx.compose.foundation.text.CoreTextFieldKt.CoreTextField(CoreTextField.kt:532)
	at androidx.compose.foundation.text.BasicTextFieldKt.BasicTextField(BasicTextField.kt:275)
	at androidx.compose.material.OutlinedTextFieldKt.OutlinedTextField(OutlinedTextField.kt:304)
	[...]
	at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:252)
	at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source)
	at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3183)
	at androidx.compose.runtime.ComposerImpl.recompose$runtime(Composer.kt:3148)
	at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:746)
	at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:876)
	at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:107)
	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:485)
	at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:454)
	at androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume(BroadcastFrameClock.kt:42)
	at androidx.compose.runtime.BroadcastFrameClock.sendFrame(BroadcastFrameClock.kt:71)
	at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:412)
	at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:306)
	at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:305)
	at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:102)
	at androidx.compose.ui.awt.ComposeLayer.access$catchExceptions(ComposeLayer.desktop.kt:82)
	at androidx.compose.ui.awt.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:305)
	at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:510)
	at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
	at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invokeSuspend(Direct3DRedrawer.kt:37)
	at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.kt)
	at org.jetbrains.skiko.redrawer.Direct3DRedrawer$frameDispatcher$1.invoke(Direct3DRedrawer.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:106)
	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)

asapha avatar Sep 01 '22 19:09 asapha

@asapha, thanks! Indeed, we also need to catch IllegalStateException

igordmn avatar Sep 02 '22 14:09 igordmn

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

okushnikov avatar Jul 14 '24 17:07 okushnikov