Skip to content

build!: raise the compile baseline to Java 21 and restore the reverted language features#222

Open
eschizoid wants to merge 3 commits into
mainfrom
feat/java-21-baseline
Open

build!: raise the compile baseline to Java 21 and restore the reverted language features#222
eschizoid wants to merge 3 commits into
mainfrom
feat/java-21-baseline

Conversation

@eschizoid

@eschizoid eschizoid commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Closes #217. Raises the compile baseline from Java 17 to Java 21 (LTS) across all modules — toolchain stays at 25 — and restores every language feature the Java 17 downgrade (#80) stripped, except unnamed _ (JEP 456 needs 22+; deliberately out of scope at an LTS floor).

What's restored

  • Pattern-match switch over the sealed hierarchies in Either, Validated, EitherK, ValidatedK, DeepMap (the fieldIsoOf dispatch and extractDefaultStrategy; the sequential applyForward/applyBackward routing passes intentionally stay as chains), ValidatedOrderController — the "unreachable" fallthrough throws are deleted (exhaustiveness is compiler-checked now).
  • Record patterns in Validated.combine, ValidatedK.map2, DeepMap.
  • Sequenced CollectionsgetFirst() across codegen processors, demos, tests. Positional get(0)/get(1) pairs (Map key/value type args) intentionally stay indexed.
  • try-with-resources on ExecutorService in BoundedAsyncTest + the Telescope javadoc example.
  • Telescope.BridgeTelescope back to private — Java 21 accepts a private permitted subclass in the same compilation unit, so build: cross-compile to Java 17 (--release 17) #80's accessibility workaround goes away.
  • options.release = 21 in all 14 module build files, @SupportedSourceVersion(RELEASE_21) on the 5 processors, README JVM badge → 21+.

Correction vs the issue text

#217 listed "restore BridgeProcessor switch emission" — that item is moot: the sealed-bridge dispatch emission was independently rewritten (after #80) to the lattice-routed Match.of(…).when(…).exhaustive() runtime builder, which is source-level-agnostic. Generated navigators/bridges therefore do not impose a -source 21 requirement on consumers; the only consumer-facing constraint is the runtime floor below.

Breaking change (release-notes callout)

  • Consumers on Java 17–20 can no longer run telescope — artifacts are compiled at --release 21 (class-file 65), so the runtime floor is Java 21.

Deliberate behavior change (found in review)

Validated.combineAll now throws NullPointerException on a null list element where the old instanceof chain silently dropped it (producing a Valid with a shorter list — silent corruption). Loud failure over silent element loss; no caller or test relied on the old behavior.

This should ride the next minor-at-least version bump with the baseline called out in the release notes.

Test

Full ./gradlew spotlessApply build green across all 14 modules.

Note on codecov/patch

The exhaustive fieldIsoOf switch carries eight explicitly-dead throwing arms (documented in-source as DEAD-BRANCH-DEFENSIVE, "NOT coverage targets"): they exist so a future Mapping permit forces a compile error instead of silently mis-routing. codecov/patch counts those never-executed lines against the patch — that red is the deliberate price of compile-checked exhaustiveness, not a coverage gap; every reachable branch is pinned by a named test (see the review-fleet coverage report).

…d language features

Reverses the Java 17 cross-compile downgrade (#80) now that the supported floor
moves to the current LTS. The toolchain stays at 25; only --release rises.

- options.release 17 -> 21 in all 14 module build files; @SupportedSourceVersion
  RELEASE_17 -> RELEASE_21 on the five annotation processors; README JVM badge
  17+ -> 21+.
- Pattern-match switch expressions restored over the sealed hierarchies in
  Either, Validated, EitherK, ValidatedK, DeepMap, and ValidatedOrderController;
  the "unreachable" fallthrough throws are gone (exhaustiveness is
  compiler-checked). Record patterns restored in Validated.combine,
  ValidatedK.map2, and DeepMap.
- Sequenced Collections: getFirst() restored across the codegen processors,
  example demos, and tests; positional get(0)/get(1) pairs (Map key/value type
  arguments) intentionally stay indexed.
- try-with-resources on ExecutorService restored in BoundedAsyncTest and the
  Telescope javadoc example.
- BridgeProcessor emits a pattern-match switch for sealed-bridge dispatch again;
  BridgeProcessorTest assertions updated. Generated navigators and bridges now
  require consumers to compile at 21+.
- Telescope.BridgeTelescope returns to private (the Java 17 sealed-permits
  accessibility workaround is no longer needed).

BREAKING CHANGE: consumers on Java 17-20 can no longer run telescope; the
runtime floor is Java 21, and code generated by telescope-codegen requires
-source 21+ downstream. Unnamed variables (_, JEP 456) stay out of scope - they
need Java 22+ and the floor is deliberately the LTS.

Closes #217
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.13115% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.60%. Comparing base (6f789fc) to head (2523712).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...in/java/io/github/eschizoid/telescope/DeepMap.java 44.44% 9 Missing and 1 partial ⚠️
...b/eschizoid/telescope/codegen/BridgeProcessor.java 72.72% 0 Missing and 3 partials ⚠️
.../github/eschizoid/telescope/effects/Validated.java 83.33% 1 Missing and 1 partial ⚠️
.../eschizoid/telescope/codegen/FromMapProcessor.java 0.00% 0 Missing and 1 partial ⚠️
...oid/telescope/codegen/MapperVerifierProcessor.java 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##               main     #222   +/-   ##
=========================================
  Coverage     79.59%   79.60%           
  Complexity     1841     1841           
=========================================
  Files            80       80           
  Lines          5783     5790    +7     
  Branches       1215     1209    -6     
=========================================
+ Hits           4603     4609    +6     
- Misses          660      662    +2     
+ Partials        520      519    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR raises the project’s Java compile baseline to Java 21 (while keeping the Gradle toolchain at 25) and reintroduces Java 21 language/library features that were previously removed for Java 17 compatibility.

Changes:

  • Bump Gradle options.release across modules to 21, and bump annotation processors to @SupportedSourceVersion(RELEASE_21).
  • Restore Java 21 language features (pattern-matching switch, record patterns) in core and examples.
  • Adopt Sequenced Collections APIs (getFirst()) and restore ExecutorService try-with-resources usage in tests/docs.

Reviewed changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
spring-boot-starter/build.gradle.kts Raise compile release to 21.
README.md Update JVM badge to 21+.
quarkus/build.gradle.kts Raise compile release to 21.
lombok/src/main/java/io/github/eschizoid/telescope/codegen/lombok/LombokFocusProcessor.java Processor source version to RELEASE_21.
lombok/build.gradle.kts Raise compile release to 21.
internal/build.gradle.kts Raise compile release to 21.
examples/springboot/product-starter/build.gradle.kts Raise compile release to 21.
examples/springboot/org-chart/build.gradle.kts Raise compile release to 21.
examples/springboot/order-jpa/src/main/java/io/github/eschizoid/telescope/demo/spring/api/ValidatedOrderController.java Switch-based sealed dispatch in controller.
examples/springboot/order-jpa/build.gradle.kts Raise compile release to 21 (but header comment now inconsistent).
examples/springboot/invoicing/src/test/java/io/github/eschizoid/telescope/demo/invoicing/InvoiceBridgeFlowTest.java Use List.getFirst() in assertions.
examples/springboot/invoicing/build.gradle.kts Raise compile release to 21.
examples/mapstruct-vs-telescope/src/test/java/io/github/eschizoid/telescope/example/mapstruct/MapStructVsTelescopeTest.java Use getFirst() in tests.
examples/mapstruct-vs-telescope/build.gradle.kts Raise compile release to 21.
examples/library/src/main/java/io/github/eschizoid/telescope/examples/MultiEditDemo.java Use getFirst() in demo output paths.
examples/library/src/main/java/io/github/eschizoid/telescope/examples/DeepMappingDemo.java Use getFirst() in demo output paths.
examples/library/build.gradle.kts Raise compile release to 21.
core/src/test/java/io/github/eschizoid/telescope/introspection/MapperLoggingTest.java Use getFirst() for sequenced collections.
core/src/test/java/io/github/eschizoid/telescope/BoundedAsyncTest.java Restore try-with-resources on ExecutorService.
core/src/main/java/io/github/eschizoid/telescope/Telescope.java Restore try-with-resources example; make BridgeTelescope private again.
core/src/main/java/io/github/eschizoid/telescope/runtime/instances/ValidatedK.java Use record patterns for Invalid + List.getFirst() support via imports.
core/src/main/java/io/github/eschizoid/telescope/runtime/instances/EitherK.java Restore sealed switch dispatch in map2.
core/src/main/java/io/github/eschizoid/telescope/effects/Validated.java Restore sealed switch + record patterns in combine logic.
core/src/main/java/io/github/eschizoid/telescope/effects/Either.java Restore sealed switch dispatch in fold.
core/src/main/java/io/github/eschizoid/telescope/DeepMap.java Restore record patterns and sealed switch for mapping dispatch.
core/build.gradle.kts Raise compile release to 21.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/MapperVerifierProcessor.java Use getFirst() in argument selection.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/FromMapProcessor.java Processor source version to RELEASE_21; getFirst() for single arg access.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/FocusProcessor.java Processor source version to RELEASE_21; getFirst() for single element access.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/BridgeProcessor.java Processor source version to RELEASE_21; getFirst() for container/type arg access.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/BeanFocusProcessor.java Processor source version to RELEASE_21.
codegen/src/main/java/io/github/eschizoid/telescope/codegen/AbstractTelescopeProcessor.java Use getFirst() for single property handling.
codegen/build.gradle.kts Raise compile release to 21.
benchmarks/build.gradle.kts Raise compile release to 21.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread core/src/main/java/io/github/eschizoid/telescope/DeepMap.java
Comment thread examples/springboot/order-jpa/build.gradle.kts
…spatch comments

- final on the record-pattern bindings in Validated.combine / ValidatedK.map2,
  matching the convention the other pattern sites already follow.
- BridgeProcessor's sealed-dispatch comment and BridgeProcessorTest's
  DisplayName described a pattern-match switch; the emission is the
  Match.of(...).when(...).exhaustive() fluent — both now say so.
- DeepMapBranchTest javadoc reworded to describe the current routing shape in
  its own terms (sequential instanceof passes vs the compiler-checked sealed
  switch in fieldIsoOf).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 36 out of 36 changed files in this pull request and generated 1 comment.

… order-jpa header

- combineAll's sealed switch now names the failure: a null element throws an
  NPE with an API-level message instead of the bare selector NPE. Loud-failure
  behavior unchanged.
- order-jpa module header updated to the --release 21 / toolchain 25 split.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 36 out of 36 changed files in this pull request and generated no new comments.

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

Successfully merging this pull request may close these issues.

Raise release baseline to Java 21 and adopt Sequenced Collections

2 participants