style
esc
  • Loading…

Check itJava Style Guide lint kit

Conventions for writing, structuring, formatting and shipping modern Java 23 that compiles with zero warnings and no surprises.

Java 23google-java-formatMaven
Download the kit 114 checks · rule IDs on every finding

Checks a Java codebase against the Java Style Guide and reports every finding with its rule ID, linked to the rule:

billing-core/src/main/java/com/acme/billing/InvoiceService.java:41:7: MUST NOT JAVA-11.2: never ignore an exception; if doing nothing is right, name it _ and say why in a comment [chopper]
billing-core/src/main/java/com/acme/billing/Invoice.java:12:28: MUST NOT JAVA-10.7: no Optional fields (`note`): use @Nullable or an empty collection [chopper]

It runs three kinds of check:

  • The guide's own checks, always: layout and package names, one top-level type per file, wildcard and misordered imports, naming (UPPER_SNAKE_CASE only for real constants, acronyms as one word), braces and arrow switches, records that keep mutable components, Optional misuse, swallowed and over-broad catches, System.out and printStackTrace(), logger declarations and {} placeholders, preview APIs, @NullMarked packages, test naming and placement, /// doc comments on public API, TODO format, and the parent POM (--release 23, -Xlint:all -Werror, Error Prone with NullAway, Spotless, versions only in the parent). Plus the .editorconfig basics: the 100-column limit, 2-space indentation, tabs, trailing whitespace and the final newline. checks.json lists them all.
  • Spotless with --maven: ./mvnw spotless:check, the project's own google-java-format setup (chapter 6). Each unformatted hunk is reported at its line.
  • The compile with --compile: ./mvnw test-compile, so javac with -Xlint:all -Werror, Error Prone and NullAway report through the kit with rule IDs (NullAway as JAVA-10.3, MissingOverride as JAVA-08.4, raw types as JAVA-14.1, and so on). The compile stops at the first module with errors, so fix and run again.

Both Maven runs use the project's wrapper (mvnw, else mvn) and its pom.xml, so the versions are the ones the build pins. They are off by default because Maven is slow next to the kit's own checks (well under a second on most repositories). The repository's own .editorconfig is used when it has one; otherwise the kit's copy (the guide's appendix, verbatim) is.

Run it

Needs Python 3.9+, and for --maven / --compile a JDK 23 (the enforcer in the guide's parent POM rejects any other) and the project's Maven wrapper.

python3 chopper_lint.py                          # the current folder
python3 chopper_lint.py billing-core billing-api # some folders
python3 chopper_lint.py --maven                  # also ./mvnw spotless:check
python3 chopper_lint.py --maven --compile        # also Error Prone and NullAway
python3 chopper_lint.py --maven --maven-args="-o -Dmaven.repo.local=/tmp/m2"
python3 chopper_lint.py --strict                 # fail on SHOULD and AVOID too
python3 chopper_lint.py --list-checks            # what it checks

Run it from the repository root (or pass --root): the parent POM, the Maven wrapper, .java-version, Dependabot and tracked IDE files are checked only when the root itself is among the paths. Folders named target, build, out, vendor and the like are skipped, as are generated *.gen.java files.

Exit status: 1 when a MUST or MUST NOT rule is broken (any finding with --strict), else 0.

In GitHub Actions

- uses: actions/checkout@v4
- uses: carson-hopper/chopper.dev/content/styleguides/java/lint@main
  with:
    paths: .
    # compile: true    # also javac -Werror, Error Prone and NullAway

The action installs the JDK the guide pins (Temurin 23; change it with java-version) for the Maven runs, and Python if the runner has none. Findings appear as annotations on the pull request. Pin @main to a commit SHA for reproducible runs.

Silencing a finding

On the same line or the line above, with a reason:

} catch (Exception e) { // chopper-lint: allow JAVA-11.5 (the worker's top-level loop)

For a whole file: // chopper-lint: allow-file JAVA-16.1. In a pom.xml: <!-- chopper-lint: allow JAVA-19.1 (reason) -->.