Skip to content

Format Java with Spotless and palantir-java-format instead of Prettier #1464

Description

@FelixTJDietrich

Important

Deferred — do not start yet. This reformats all 2,939 files under server/src, which is the
busiest area in the repo. It currently conflicts with 5 open PRs and ~279 of their files
(#1454, #1424, #1399, #1443, #1448), three of them large feature branches.

Unblocks when the big server/ branches have merged. Re-measure before starting:
gh pr list --state open --json number,files --jq '.[] | {n:.number, s:([.files[].path|select(startswith("server/src/"))]|length)}'

We format Java with Prettier via prettier-plugin-java. That plugin's parser is decoupled from javac, and it now fails on valid Java we already have in the tree.

The trigger

Upgrading prettier-plugin-java 2.8.1 → 2.10.3 (which swapped the parser to tree-sitter) makes the format check fail outright on two files:

[error] server/src/test/java/de/tum/cit/aet/hephaestus/core/auth/oauth/ReturnToValidatorTest.java
        Error: Failed to parse: ... (ERROR (UNEXPECTED '\0'))
[error] server/src/test/java/de/tum/cit/aet/hephaestus/agent/sandbox/docker/interactive/LogSafeTest.java

The cause is ReturnToValidatorTest.java:56, which contains a NUL escape (backslash-u-0000) inside a string literal. Java resolves Unicode escapes before lexing, so the tree-sitter grammar sees a real NUL and gives up.

We are pinned to 2.8.1, so nothing is broken today — but we are stuck on an old version, and the next such gap could be a language feature rather than an escape sequence.

A formatter that parses with javac cannot have this class of bug. That is the actual argument for moving.

Proposal

Spotless (spotless-maven-plugin) with palantir-java-format.

  • Palantir is the only mainstream Java formatter that reproduces our current 4-space / 120-column style natively. google-java-format is locked to 100 columns.
  • Maven-native, so spotless:check binds to verify and the Java build stops depending on Node.
  • Spotless keeps an incremental index, so the pre-push check should get faster as well. That is what closed Only format-check changed Java files in the pre-push hook #1465.

Land it in a quiet window

This reformats all 2,939 files under server/src, and server/src is the busiest area in the repo. At the time of writing it conflicts with 6 open PRs and roughly 286 of their files (#1454, #1424, #1399, #1443, #1448, #1470), including two large feature branches.

Check that number again before starting. Get the big branches merged or rebased first, announce the window, and let people rebase once. Add the reformat commit's SHA to .git-blame-ignore-revs, which GitHub honours automatically from the repo root.

This is one PR. The formatter swap and the full reformat land together, or neither lands. Do not use ratchetFrom to convert the tree gradually — that leaves two Java styles in the repo indefinitely and turns every later diff into a guessing game about which style applies. If a quiet window is unreachable, wait; do not half-convert.

Before committing to it

Measure how far palantir's output actually is from our current Prettier output. That decides whether this is a clean swap or a style change the team needs to agree on first.

Done when

  • pnpm run format:java / format:java:check are gone, replaced by Spotless
  • CI's App Server quality gate calls Spotless
  • the reformat is one commit and is in .git-blame-ignore-revs
  • prettier and prettier-plugin-java are out of the root package.json
  • server/src is formatted consistently — no mixed styles left behind

Metadata

Metadata

Assignees

No one assigned

    Labels

    javamaintenanceChores, cleanup, non-functional improvementssize:LThis PR changes 100-499 lines, ignoring generated files.status:blockedBlocked by external dependency or other issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions