Skip to content

Add JSpecify null-safety enforcement with Error Prone + NullAway - #98

Open
jpenilla wants to merge 1 commit into
masterfrom
null-safety-tooling
Open

Add JSpecify null-safety enforcement with Error Prone + NullAway#98
jpenilla wants to merge 1 commit into
masterfrom
null-safety-tooling

Conversation

@jpenilla

@jpenilla jpenilla commented Aug 8, 2026

Copy link
Copy Markdown
Member
  • Wire net.ltgt.errorprone 5.1.0 + net.ltgt.nullaway 3.1.0 with Spring's
    recommended config: only NullAway enabled, OnlyNullMarked, JSpecifyMode,
    RequireExplicitNullMarking, Spring @contract support
  • Add org.jspecify:jspecify (Boot BOM-managed) and @NullMarked
    package-info for every package
  • Mark genuinely-nullable entity fields @nullable to match the DB schema
  • Fix latent NPE in PatchService.finishWorkOnPatch; use requireNonNull
    where invariants are provable
  • Add serialVersionUID to PatchId

Stack created with GitHub Stacks CLIGive Feedback 💬

- Wire net.ltgt.errorprone 5.1.0 + net.ltgt.nullaway 3.1.0 with Spring's
  recommended config: only NullAway enabled, OnlyNullMarked, JSpecifyMode,
  RequireExplicitNullMarking, Spring @contract support
- Add org.jspecify:jspecify (Boot BOM-managed) and @NullMarked
  package-info for every package
- Mark genuinely-nullable entity fields @nullable to match the DB schema
- Fix latent NPE in PatchService.finishWorkOnPatch; use requireNonNull
  where invariants are provable
- Add serialVersionUID to PatchId

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 introduces JSpecify-based null-safety enforcement by wiring Error Prone + NullAway into the Gradle build and marking packages as @NullMarked, then updates key model/service/controller code to align with the new nullability rules.

Changes:

  • Configure Gradle to run NullAway (with JSpecify mode) via Error Prone, and add JSpecify annotations as a compile-time dependency.
  • Add @NullMarked package-level annotations across the application to make non-null the default.
  • Update Patch/PatchService/ApiController to make nullable state explicit and reduce null-related runtime failures; add serialVersionUID to PatchId.

Reviewed changes

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

Show a summary per file
File Description
build.gradle.kts Adds Error Prone + NullAway wiring and JSpecify dependency to enforce null-safety at compile time.
src/main/java/io/papermc/patchroulette/package-info.java Marks the root package as @NullMarked.
src/main/java/io/papermc/patchroulette/config/package-info.java Marks config package as @NullMarked.
src/main/java/io/papermc/patchroulette/controller/package-info.java Marks controller package as @NullMarked.
src/main/java/io/papermc/patchroulette/controller/ApiController.java Propagates nullable patch fields through API DTOs and tightens local null handling in stats computation.
src/main/java/io/papermc/patchroulette/model/package-info.java Marks model package as @NullMarked (enables NullAway checking for entities/IDs).
src/main/java/io/papermc/patchroulette/model/Patch.java Marks DB-nullable fields as @Nullable and refines duration update local naming.
src/main/java/io/papermc/patchroulette/model/PatchId.java Adds serialVersionUID and introduces a NullAway suppression for JPA no-arg construction.
src/main/java/io/papermc/patchroulette/repository/package-info.java Marks repository package as @NullMarked.
src/main/java/io/papermc/patchroulette/service/package-info.java Marks service package as @NullMarked.
src/main/java/io/papermc/patchroulette/service/PatchService.java Adjusts responsible-user handling to address a null-related failure mode.
src/main/java/io/papermc/patchroulette/util/package-info.java Marks util package as @NullMarked.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +91 to +93
final String responsibleUser = Objects.requireNonNull(
patch.getResponsibleUser(), "Patch " + patchId + " has no responsible user");
if (!responsibleUser.equals(user)) {
Comment on lines 23 to +27

@Enumerated(EnumType.ORDINAL)
private Status status;

@Nullable
private String path;

// Required by JPA; fields are always set via the constructor or by Hibernate reflection.
@SuppressWarnings("NullAway")
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.

2 participants