
Javaru
Kotlin Coroutine Confidence: Code does not run (pg 225)
When I run pets/v23
from page 225, I get a quick flash of the “control panel” window, and then the program exits. There is no output in the console other than:
Process finished with exit code 0
Same problem for pets/v24
.
For pets/v25
and pets/v26
, I get a single window, and then after the 15 second delay, rather than a second slide show starting, the program exits.
book-kotlin-coroutine-confidence version B3
Marked As Solved

sam-cooper
Wow, thanks for spotting this! I’m embarrassed I missed it.
Looks like the bug is in the suspending createWindow()
function. When we invoke the block()
parameter (which, by the way, I’ve renamed to onWindowOpened()
after our previous thread), we call window.dispose()
immediately afterwards. But the lambda function doesn’t just need to wait for its own code; it also has a CoroutineScope
receiver which it can use to launch additional coroutines.
The solution is to wrap block()
/onWindowOpened()
with its own coroutineScope { … }
:
suspend fun createWindow(
title: String,
onWindowOpened: suspend CoroutineScope.(JFrame) -> Unit
): Unit = withContext(Dispatchers.Main) {
val window = JFrame(title)
window.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE
window.size = Dimension(400, 300)
launch {
window.addWindowListener(object : WindowAdapter() {
override fun windowClosed(e: WindowEvent) = this@launch.cancel()
})
window.isVisible = true
try {
coroutineScope { onWindowOpened(window) }
} finally {
window.dispose()
}
}
}
This ensures the try
block waits for the child coroutines as well as the suspending code. Adding a CoroutineScope
receiver to an already-suspending function is a bit of an unusual pattern—it’s something I’d only ever really do in higher-order functions like this one. You can see the same pattern in the launch()
and async()
functions. It’s really just a convenience thing. Without it, callers would still be able to launch child coroutines by adding a coroutineScope()
block inside the lambda code block. In other words, the two working options would be:
-
createWindow(…) { launch { … } }
+coroutineScope { onWindowOpened(window) }
, or -
createWindow(…) { coroutineScope { launch { … } } }
+onWindowOpened(window)
Evidently I changed my mind halfway through implementing it, and ended up halfway between the two options.
I might add a quick note next to the original createWindow()
function explaining this extra coroutineScope()
, since it’s a little unusual.
Thank you again for reporting the bug!
Popular Pragmatic Bookshelf topics










Other popular topics










Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /rails
- /js
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /ash
- /vscode
- /opensuse
- /centos
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /textmate
- /react-native
- /sublime-text
- /kubuntu
- /arch-linux
- /ubuntu
- /revery
- /spring
- /django
- /manjaro
- /diversity
- /lua
- /nodejs
- /julia
- /slackware
- /c
- /neovim