Claude ff6130bede Add sealed module: modelling domains with sealed types and exhaustive switch
Payment model, permits and the three modifiers, default-branch trap, generic and recursive hierarchies, visitor comparison, run-time enforcement, modules. Transcripts from JDK 21, 25 and 27.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
2026-09-24 12:03:59 +00:00

javademos

Runnable companion code for the ankurm.com post "Java 27 Is Out: Every JEP, Plus the Java 26 Changes You Skipped", for the Java version guides (https://ankurm.com/java-21-to-25-lts-features/), and for two standalone deep dives: Stream Gatherers (JEP 485) and Scoped Values vs ThreadLocal (JEP 506). Every number and transcript in the post comes from a file in docs/output/, produced by a script in scripts/.

What was tested against

Thing Version Note
JDK 21 (LTS) Amazon Corretto 21.0.12.1 the start of the 21 to 25 lane
JDK 25 (LTS) Temurin 25.0.4.1+1 the baseline for "broke on 26"
JDK 26 Amazon Corretto 26.0.2.1 GA 2026-03-17, non-LTS
JDK 27 Amazon Corretto 27+35 GA 2026-09-15, non-LTS
Containers amazoncorretto:23, :24 (when did it change?), :26, :27 same vendor for both, so only the JDK version changes
JOL 0.17 downloaded and sha1-checked by scripts/object-headers.sh

Next LTS: Java 29, September 2027 (Oracle Java SE Support Roadmap). Layout: g1-container/, object-headers/, jep-tour/ (27 features and broken/ 26-era sources), recap26/ (the Java 26 lane), lanes/ (the 21 to 25 hub demos, the AI prompts in lanes/prompts/ and the build-file demo in lanes/upgrade/), other-changes/, api-diff/, gatherers/ (JEP 485, standalone post), scoped-values/ (JEP 506 vs ThreadLocal, standalone post).

Quickstart

export JDK21=/path/to/jdk-21 JDK25=/path/to/jdk-25 JDK26=/path/to/jdk-26 JDK27=/path/to/jdk-27   # defaults are in scripts/env.sh
./scripts/jep-tour.sh          # the five 27 feature demos, self-asserting
./scripts/recap26.sh           # the 26 recap lane
./scripts/lanes.sh             # the 21 to 25 hub claims, checked on 21, 23, 24, 25, 26, 27
./scripts/upgrade.sh           # the build-file half: Maven, Gradle, Lombok, --release, jdeps (needs Maven Central)
./scripts/gatherers.sh         # Stream Gatherers (JEP 485): every built-in gatherer, a custom one, mapConcurrent
./scripts/scoped-values.sh     # Scoped Values vs ThreadLocal (JEP 506): API, inheritance, memory (needs jcmd on PATH)
./scripts/run-all.sh           # regenerate every docs/output/*.txt (about 15-20 minutes; needs Docker)

Timings, RSS, GC counts and the Vector species are machine dependent; treat them as shape, not results. Everything else is byte-stable.

Chapters

# Chapter
1 What shipped, and what to believe
2 G1 becomes the default, even on one CPU (JEP 523)
3 Compact object headers (JEP 534)
4 Post-quantum TLS (JEP 527)
5 Primitive patterns (JEP 532)
6 Lazy constants (JEP 531)
7 Structured concurrency (JEP 533)
8 PEM encodings (JEP 538)
9 JFR redaction (JEP 536) and the Vector API (JEP 537)
10 Other 27 changes
11 Recap: the Java 26 changes you skipped
12 Version lanes: 25 to 29
13 Upgrade checklist
14 The 21 to 25 lane: every claim in the hub posts, checked
15 Build files: Maven, Gradle and Lombok on the way to 25
16 Stream Gatherers (JEP 485)
17 Scoped values vs ThreadLocal (JEP 506)

Standalone article modules (no docs/ folder)

These modules keep only sources, a run.sh and their transcripts (output/). The explanation lives in the article itself, in collapsible sections.

Module Article What it demonstrates
jep512/ Compact Source Files and Instance Main Methods in Java 25 (JEP 512) java Hello.java on JDK 21 vs 25 vs 27, the class javac builds around void main(), implicit java.base imports, java.lang.IO, the measured launch order, a private-constructor difference between 25 and 27
jep513/ Flexible Constructor Bodies in Java 25 (JEP 513): Validate Before super() statements before super(...)/this(...), the parent-calls-child bug and its fix, twelve compile errors that remain with the 25 and 27 wordings side by side, --release rejection
jep511/ Module Import Declarations in Java 25 (JEP 511) import module java.base; against seven single imports, ambiguity errors and how single-type, on-demand and same-package names beat a module import, what one module import does and does not bring in (java.sql does not give java.base; java.se needs --add-modules), named modules, JEP 512 compact files, jshell's default imports, identical bytecode
patterns/ Pattern Matching in Java: switch, Record Patterns and Primitive Patterns (JDK 21 to 27) type and record patterns, guards and dominance errors, sealed exhaustiveness (with JDK 27's new missing patterns lines), MatchException from a throwing accessor and from separate compilation, unnamed patterns, primitive patterns with --enable-preview and the preview class-file trap
sealed/ Sealed Classes and Interfaces: Modelling Domains with Exhaustive switch a Payment model, permits and the three subclass modifiers, the default trap, generic and recursive hierarchies, the visitor for comparison, run-time enforcement and modules

Captured output (docs/output/)

File Produced by What it is
01-03 g1-default.sh which collector each JDK picks, by container size; the opt-out
04-06 g1-cost.sh, g1-tuning.sh what G1 costs on one CPU, and two tested explanations
10-15 object-headers.sh JOL instance sizes on 26, 27, 27 opted out; the JOL record failure and workaround
20-broken-* broken-on-27.sh javac's own messages for 26-era preview code on 27
21-25 jep-tour.sh the five 27 feature demos
30-32 tls-pq.sh key-exchange matrix, ClientHello size, the opt-out
40 jfr-redaction.sh five redaction configurations
50-52 api-diff.sh public API diffs, 26 to 27, 25 to 26, Vector only
60-62 other-changes.sh removed options, behaviour changes, new 27 API
70-75 recap26.sh final-field mutation, AOT cache matrix and startup, removals, 26 API, HTTP/3
92-97 upgrade.sh Maven release 25 on JDK 21, 25, 27, Gradle 8 vs 9 on JDK 25, --release vs -source/-target, Lombok and Mockito by version, jdeps --jdk-internals
80-91 lanes.sh the 21 to 25 hub claims on JDK 21, 23, 24, 25, 26, 27: scoped values, structured concurrency, finalization, pinning, ZGC flags, warnings
98 gatherers.sh the four built-in gatherers, mapConcurrent + virtual threads, a custom Gatherer, Collector vs Gatherer
99 scoped-values.sh ScopedValue API and rebinding, why plain threads don't inherit a binding, memory vs ThreadLocal two ways (heap delta, then jcmd object census)

Not reproduced

jdk.java.net/27 and openjdk.org/jeps returned 403 while this was written; the JEP list was cross-checked against four secondary sources and the JDK binaries themselves. HTTP/3 was not spoken to a real HTTP/3 server (no UDP egress). JEP 522 was not benchmarked. JDK-8377013 could not be reproduced.

MIT licensed, see LICENSE.

S
Description
Runnable companion code for the ankurm.com Java 27 / Java 26 posts and the Java version guides
Readme MIT
290 KiB
Languages
Java 66.6%
Shell 31.8%
Python 1.6%