Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Null Safety in Java: JSpecify in Action

Null Safety in Java: JSpecify in Action

NullPointerExceptions are among the most common errors in Java applications. JSpecify now offers a standardized approach to clearly document nullability in Java code and verify it through static analysis. Open-source projects like Spring Boot have begun extending their code with JSpecify.

In this presentation, I'll demonstrate how I successfully implement JSpecify in all new client projects.

First, we'll look at what JSpecify is and how it differs from other nullability annotations like JetBrains' @Nullable or JSR-305.

Then we'll move on to practical application. I'll show you how to configure JSpecify in a Spring Boot project and how to integrate it with Maven, NullAway, ErrorProne, and IntelliJ.

We'll also discuss how to migrate existing projects to greater null safety step by step and which typical pitfalls to avoid.

This presentation is aimed at Java developers who want to improve their code quality. Basic knowledge of Spring Boot is helpful, but not required.

After this presentation, you'll be able to use JSpecify in your own projects and know what to look out for.

Avatar for Simon Martinelli

Simon Martinelli PRO

February 05, 2026

Resources

More Decks by Simon Martinelli

Other Decks in Programming

Transcript

  1. About Me • 30 years in Software Engineering • 25

    years with Java • Independent Consultant since 2009 • Teaching at two Universities • Co-lead Berne, JUG Switzerland
  2. The Billion Dollar Mistake • Tony Hoare introduced the null

    reference in ALGOL W in the 1960s • Many years later 2009, he said it was a mistake that has cost the industry billions in bugs, crashes, and wasted time
  3. The Core Problem Part of the contract Invisible in the

    type Fails in production Nullability is part of every API contract Java types cannot express non-nullability The result: NullPointerException at runtime
  4. What We Tried Defensive null checks Many if (x !=

    null) Code reviews Doesn’t find every problem Optional Not a good fit for parameters @Nullable annotations No standard
  5. Why Optional Is Not Enough Optional solves one narrow problem

    But Optional is not a nullsafety system Models “value may be absent” for return values Does not express parameter contracts Helps avoid null in fluent APIs Does not define field or property nullability Does not work across layers consistently
  6. What Went Wrong with JSR-305 Never finalized No active ownership

    The JSR stayed dormant Nobody drove it forward Different interpretations Ecosystem fragmentation Each tool read it differently Many incompatible variants
  7. Jakarta Validation aka Bean Validation Answers a different question Is

    reactive, not preventive No compile-time guarantees • Is the value valid at runtime? • Violations are detected after the code runs • Compiler allows null dereferences • Not: can this value ever be null? • Often at REST or persistence boundaries • IDE cannot enforce API contracts
  8. Checker Framework The Checker Framework extends Java’s type system with

    pluggable type checkers. Supports nullness, immutability, units. → checkerframework.org The Core Problem: It’s Too Heavy for Most Teams Cognitive overhead is high Annotation explosion Poor fit for incremental adoption Tooling friction in daily development Ecosystem alignment is weak
  9. Vendor-Specific Nullability Examples you probably know: They all try to

    answer the same question: JetBrains @Nullable @NotNull Can this be null? No Standard! Spring AndroidX · Eclipse · FindBugs · … @Nullable @NonNullApi • JetBrains annotations work very well in IntelliJ IDEA @Nullable @NonNull • Spring annotations integrate nicely with Spring Framework
  10. How Kotlin Handles Nulls • Nullability is part of the

    type system • Compiler enforces null check
  11. What Java Can Learn from Kotlin • Make nullability explicit

    • Fail fast at compile time • Clear contracts between APIs • https://openjdk.org/jeps/8303099
  12. Why JSpecify Exists • Standardized, minimal, well-defined semantics • Tool-agnostic

    • Designed for wide adoption • https://jspecify.dev
  13. JSpecify Core Principles • Non-null by default • Nullable and

    NonNull • Nullable is explicit • Defaults via package or class annotations
  14. Nullability as a Contract @NullMarked vs Non-null unless declared Nullable

    @NullUnmarked Nullness unspecified – legacy behaviour Caller Callee Violations must respect the non-null contract must handle nullable inputs become compile-time errors
  15. Tooling Makes It Real Typical toolchain Annotations alone are documentation

    IDE support Static analysis enforces contracts NullAway Error Prone Build-time feedback Maven or Gradle
  16. What is Error Prone? Enhances the Java compiler Originally developed

    at Google • Runs during compilation • Used on very large Java codebases • Extends javac with additional checks • Focused on real, recurring bugs • Finds bugs before the code runs • Low false-positive rate → errorprone.info
  17. What is NullAway? A null-safety checker • Built on top

    of Error Prone • Focused exclusively on nullability • Enforces null contracts at compile time → github.com/uber/NullAway Originally developed at Uber to reduce production NullPointerExceptions
  18. NullAway in the Toolchain JSpecify Error Prone NullAway defines what

    is allowed provides how to analyze enforces the rules
  19. Migration Strategy 1 2 3 Don’t annotate everything at once

    Start with public APIs Use package-level defaults Small, reviewable steps beat a big-bang migration That’s where contracts matter most @NullMarked @NullUnmarked
  20. Best Practices Non-null by default API boundaries first … everywhere

    Annotate the public surface before the internals Fix design, not warnings! A warning is a hint about the contract, not noise to suppress
  21. Common Pitfalls Mixing annotation types Overusing @Nullable JPA Entities are

    special JSpecify, JetBrains, Spring … pick one If everything may be null, nothing is guaranteed Fields are populated by the framework, not the constructor
  22. Conclusion • Null safety is API design • Static analysis

    turns intent into guarantees • JSpecify brings standardization • Java is constantly evolving
  23. Thank you! • Web martinelli.ch • EMail [email protected] • Bluesky

    @martinelli.ch • X/Twitter @simas_ch • LinkedIn https://linkedin.com/in/ simonmartinelli