Skip to content

build: move to Java 21 - #161

Merged
uniqueg merged 6 commits into
devfrom
build/66-java-21
Nov 13, 2026
Merged

uniqueg merged 6 commits into
devfrom
build/66-java-21

Conversation

@uniqueg

@uniqueg uniqueg commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Summary

First step of the move to Spring Boot 3 and later (#66): TESK API builds, tests and runs on Java 21, still on Spring Boot 2.7 (which supports Java 21).

  • java.version 21; Eclipse Temurin 21 JDK and JRE in the Dockerfile (pinned by digest); the CI job Test on Java 21. The new base image (Ubuntu 26.04.1) already has the fixed apt (3.2.1ubuntu0.1), so the upgrade step for CVE-2026-109518 goes.
  • Bug found on Java 21: TesInput checked "URL or content required" with @ScriptAssert(lang = "javascript"). Java 15 and later have no JavaScript engine, so every task with inputs failed with 500. An @AssertTrue method (as TesOutput already uses) checks the same; the message now names the field (Field 'inputs[0].urlOrContentGiven' URL or content required instead of Field 'inputs[0]' URL or content required, checked on Java 8). Blank URLs are checked with isBlank (Unicode white space, as JavaScript's trim did). Regression tests for blank URLs and empty content added, plus unit tests of the check. The development docs say that this check is hand-written in the generated TesInput.
  • The unit tests open java.util and java.lang (argLine) for system-rules' EnvironmentVariables, until the tests move to JUnit 5.
  • The CI job Lint stays on Java 8 (so code must stay parsable by Java 8 for now, as the docs say): google-java-format 1.7 doesn't run on Java 21, and newer versions reformat about 30 files; that reformat gets its own PR (so it can go into .git-blame-ignore-revs), after the open PRs that change Java code.
  • Docs: README, development, deployment, upgrade notes (JAVA_OPTS options that Java 21 removed stop the JVM; the changed validation message). Dependabot comments updated (Temurin stays on 21).

Closes #162

How it was verified

  • JAVA_HOME=<JDK 21> ./mvnw clean verify: 18404 unit tests and 99 integration tests pass, coverage checks met. Before the fix: 4 failures (500 on task creation) and 34 errors (InaccessibleObjectException from system-rules).
  • JAVA_HOME=<JDK 8> ./mvnw spotless:check checkstyle:check: passes.
  • The old message, on Java 8 with the old TesInput: Field 'inputs[0]' URL or content required (test passed with that expectation).
  • docker build and the CI smoke script (Check responses of ci.yml) against the Java 21 image: pass (both profiles, arbitrary UID, read-only root file system, Swagger UI on).
  • mkdocs build --strict and actionlint: pass.
  • CI on f0b9945: all checks pass (CI passed: Lint, Test, Docs, Smoke test, Scan image with no new findings; CodeQL; Codecov project and patch).

Overlaps

Declined review findings

  • Keep the old message text exactly (custom class-level constraint): the codebase already uses @AssertTrue methods for such checks (TesOutput), messages are for people, and the change is in the upgrade notes.
  • Repeated expected message in the controller test as a constant: the test lists the expected texts per fixture, as the neighbouring tests do.
  • --add-opens for Failsafe too: no integration test needs it; it goes with the move to JUnit 5.

Open questions

None.

🤖 Generated with Claude Code

Summary by Sourcery

Move TESK API builds, tests, and runtime containers to Java 21 while preserving input validation behavior and compatibility with existing lint tooling.

Bug Fixes:

  • Replace JavaScript-based input validation with Java-compatible validation so task creation continues to accept valid inputs and correctly rejects missing, blank, or empty sources on Java 21.

Enhancements:

  • Upgrade the application, test CI job, and container runtime from Java 8 to Java 21 while retaining Java 8 for formatting and linting.
  • Add the required test-module access configuration for Java 21 and document runtime, development, deployment, and upgrade implications.

Build:

  • Update the Maven Java version and pinned Eclipse Temurin build and runtime images to Java 21.

CI:

  • Run the main test workflow on Java 21 while keeping linting on Java 8 for compatibility with the existing formatter.

Documentation:

  • Document Java 21 requirements, remaining Java 8 linting constraints, JVM option compatibility, and the updated input validation message.

Tests:

  • Add regression and unit coverage for blank URLs, empty content, and JavaScript-compatible whitespace handling.

Chores:

  • Update Dependabot guidance to track Java 21 base images and dependencies independently of the Spring Boot 3 migration.

uniqueg and others added 3 commits November 13, 2026 22:06
The @ScriptAssert on TesInput needs a JavaScript engine, which Java 15
and later no longer have: on Java 21, every task with inputs failed
with 500. An @AssertTrue method checks the same (a url that isn't
blank, or content that isn't empty), so the message now names the
field inputs[N].urlOrContentGiven. Tests for blank URLs and empty
content added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build, test and run on Java 21 (Eclipse Temurin 21 in the image, CI job
Test on Java 21), with Spring Boot 2.7 as before: the first step of the
move to Spring Boot 3 and later (#66). The new base image has the fixed
apt, so the upgrade step goes. The unit tests open java.util and
java.lang for system-rules' EnvironmentVariables. Lint stays on Java 8,
as google-java-format 1.7 doesn't run on Java 21 and newer versions
reformat the code. Docs and upgrade notes updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Say that .env.example is the only committed env file, that all
settings are read on the server at runtime, that the image holds no
env files and takes no build settings, and how to pass settings to a
container. Replace the stale VITE_HOST_URI note and fix the link to
the deployment guide.

Closes #53

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

API

Replace JavaScript-based input validation with a Java-compatible check while preserving the API’s source requirements and documenting the resulting validation message change.

  • src/main/java/uk/ac/ebi/tsc/tesk/tes/model/TesInput.java L193-216 (+3 small edits)

Configuration

Move the build, test job, and container images to Java 21 while retaining Java 8 for linting and removing the obsolete apt upgrade step.

  • .github/dependabot.yml L6-7, L41-43
  • .github/workflows/ci.yml L94-97, L133
  • Dockerfile L2-4, L18
  • pom.xml L25, L296-299, L403-404

Documentation

Explain the Java 21 development and deployment requirements, the retained Java 8 lint constraint, and upgrade considerations for JVM options and input-validation messages.

  • README.md L62-64
  • docs/deployment.md L25, L69
  • docs/development.md L4-6, L68-76, L225-228
  • docs/upgrading.md L5-19

Tests

Add unit and API regression coverage for missing, blank, and empty input sources, including JavaScript-compatible whitespace behavior.

  • src/test/java/uk/ac/ebi/tsc/tesk/tes/api/TasksApiControllerTest.java L246-254
  • src/test/java/uk/ac/ebi/tsc/tesk/tes/model/TesInputTest.java L1-32
  • src/test/resources/invalid_tasks/inputs/blank_url.json L1-20
  • src/test/resources/invalid_tasks/inputs/empty_content.json L1-20

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.07%. Comparing base (0d6904f) to head (5c35e32).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #161      +/-   ##
==========================================
+ Coverage   75.02%   75.07%   +0.05%     
==========================================
  Files          71       71              
  Lines        3267     3274       +7     
  Branches      385      386       +1     
==========================================
+ Hits         2451     2458       +7     
  Misses        663      663              
  Partials      153      153              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@uniqueg
uniqueg marked this pull request as ready for review November 13, 2026 21:42
@sourcery-ai

sourcery-ai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Linked issues

Checked at commit 14fa65f

#162 build: move to Java 21 · 5 of 6 met · 1 to check by hand

# Requirement Status Notes
1 Set java.version and the Docker JDK/JRE to Java 21, and run the CI Test job on Java 21. ✅ Met The Maven property, both Docker base images, and the CI Test job use Java 21.
2 Replace TesInput's JavaScript @ScriptAssert with @AssertTrue, so tasks with inputs work on Java 21 and missing sources are rejected with 400. ✅ Met The check is now a Java method, with unit tests for valid and invalid sources and controller regression cases for blank URLs and empty content.
3 Open java.util and java.lang to unit tests for system-rules' EnvironmentVariables. ✅ Met The Surefire argLine adds both required --add-opens options.
4 Keep lint on Java 8. ✅ Met The CI Lint job remains on Java 8; the documentation explains the formatter constraint.
5 Update the README, development and deployment docs, and upgrade notes. ✅ Met The changed Java version and its development, deployment, and upgrade implications are documented.
6 ./mvnw clean verify passes on Java 21 and the CI jobs pass, including the image scan and smoke test. 👀 Check by hand (external system) Confirm the CI run for this revision shows the Java 21 verification, image scan, and smoke test passing.

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/main/java/uk/ac/ebi/tsc/tesk/tes/model/TesInput.java" line_range="203" />
<code_context>
+  @JsonIgnore
+  @AssertTrue(message = "URL or content required")
+  public boolean isUrlOrContentGiven() {
+    return (url != null && !url.isBlank()) || (content != null && !content.isEmpty());
+  }
+
</code_context>
<issue_to_address>
**Whitespace-only URLs pass validation**

When the URL contains only characters such as NBSP or BOM that JavaScript `trim()` removes but `String.isBlank()` does not, and content is null or empty, `isUrlOrContentGiven()` accepts the URL as a source, so validation passes and task creation proceeds with an unusable input instead of returning 400; fetching the input then fails.

Check the URL using whitespace trimming that matches JavaScript `trim()` before treating it as present.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and java 21 may reject JVM options that worked on Java 8, preventing the application from starting and causing an outage; reverting the image restores service, but cannot undo the outage that already occurred.

Blocking findings: src/main/java/uk/ac/ebi/tsc/tesk/tes/model/TesInput.java:203


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

uniqueg and others added 3 commits November 13, 2026 23:21
Match the white space that JavaScript's trim removed (NBSP, BOM,
U+2007, U+202F and the other ECMAScript WhiteSpace and
LineTerminator characters) when checking an input's URL, so such URLs
fail validation as before. Raised by Sourcery on #161.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot 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.

Sourcery assessment

Approved.

@uniqueg
uniqueg merged commit ad32c6b into dev Nov 13, 2026
25 checks passed
@uniqueg
uniqueg deleted the build/66-java-21 branch November 13, 2026 22:34
uniqueg added a commit that referenced this pull request Nov 14, 2026
Brings in #161, #174, #175, #176, #178, #181, #183 and #184. The
conflict in docs/upgrading.md is resolved by merging both lists under
"To 1.3.0": the upgrade order for filer labels and Java 21 come first,
and the TES 1.1 fields item no longer says that ignore_error: true is
refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uniqueg added a commit that referenced this pull request Nov 14, 2026
Lists the changes merged into dev since the notes were written:
Java 21 (#161), ignore_error (#174), the resource server (#175),
output file logs (#176), the Kubernetes client (#178), Dependabot
labels (#181), the executor job selector (#183) and full test coverage
(#184). Adds a Breaking changes section, as in the 1.2.0 notes, and
sets date-released to the planned tag date, 2026-11-16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

build: move to Java 21

1 participant