# structured-concurrency-final — Structured Concurrency, final in JDK 28 (JEP 543) Companion code for the ankurm.com article **Structured Concurrency Is Final in JDK 28 (JEP 543): From Preview to Production** (). The explanation lives in the article, in collapsible sections; this folder holds the runnable sources and the transcripts they produced. ```bash JDK25=/path/to/jdk-25 JDK26=/path/to/jdk-26 JDK27=/path/to/jdk-27 JDK28=/path/to/jdk-28 ./run.sh # regenerates output/*.txt ``` ## What was tested against | Thing | Build | Note | |---|---|---| | JDK 28 | Temurin `28-beta+21-ea` (28-ea+21, build of 2026-10-22) | **early access**; JEP 543 status "Integrated", GA proposed 2027-03-09. No flags needed | | JDK 27 | Temurin 27.0.1.0.2+1 | GA 2026-09-15. Seventh preview (JEP 533): needs `--enable-preview` | | JDK 26 | Temurin 26.0.2.1+1 | sixth preview (JEP 525), for the old-API compile results | | JDK 25 | Temurin 25.0.5+8 | fifth preview (JEP 505), for the API diffs | `javap` prints identical `StructuredTaskScope` signatures on 27 and on 28-ea+21 (`output/09-api-diff.txt`). Nothing here was run on a GA JDK 28, because none exists yet. ## Layout - `src/` — runnable demos, no flags on JDK 28: `Server` (the canonical program), `Unstructured` and `FailFast` (the thread leak and its fix), `Joiners` (the built-in joiners), `Failures` (structure violations and failure handling), `Timeouts`, `CollectingJoiner` (a custom joiner), `RandomTasks` (seeded), `StuckClose` (a subtask that ignores interrupts), `ThreadDump` (JSON thread dump with the scope hierarchy), `ScopedValues`, `Snippets` and `QuickReference` (the short fragments quoted in the article). - `broken/` — six sources that compile on JDK 26 and fail on 28: `MissingCatch`, `OldFailedException`, `OldTimeoutException`, `AwaitAll`, `OldJoiner`, `ShutdownOnFailure`. - `output/` — one transcript per script step; `run.sh` regenerates all of them. | Transcript | What it shows | |---|---| | `01-server.txt` | the canonical program on 28 (no flags), on 27 (`--enable-preview`), and the 27 compile errors without the flag | | `02-unstructured-vs-structured.txt` | `ExecutorService` leaks the sibling; `StructuredTaskScope` interrupts it | | `03-joiners.txt` | `allSuccessfulOrThrow`, `anySuccessfulOrThrow`, `awaitAllSuccessfulOrThrow`, `allUntil`, the `Function` overloads | | `04-failures.txt` | `get()` before `join()`, no `join()`, non-owner `fork`, out-of-order close, join twice, cause pattern matching | | `05-timeouts-and-custom-joiner.txt` | scope timeouts, a partial-result `timeout()`, thread factory, a custom joiner | | `06-thread-dump.txt`, `15-jcmd-thread-dump.txt` | the scope as a container in a JSON thread dump (in-process and via `jcmd`) | | `07-scoped-values.txt` | subtasks inherit a `ScopedValue` binding, a plain thread does not | | `08-api-28.txt`, `09-api-diff.txt` | `javap` of the API on 28, and the diffs 25 to 26 to 27 to 28 | | `10-broken-old-api.txt` | the compiler's messages for 25/26-era code on 28 | | `11-preview-traps.txt` | a class compiled with preview on 27 does not load on 28; `--release 27` on a 28 compiler | | `12-snippets.txt` | the short fragments in the article compile and run | | `13-random-tasks.txt`, `14-stuck-close.txt` | seeded fan-out with one slow task; a subtask that ignores interrupts | Everything is byte-stable between runs (timings are reduced to booleans). The JEP statements (what changed in each preview) come from the JEP texts on openjdk.org; only the 25 to 28 API differences were checked against binaries.