Proposal: Use JSpecify annotations for nullability instead of Jakarta annotations
Summary
This issue proposes migrating the library’s nullability annotations from Jakarta (jakarta.annotation.*) to JSpecify (org.jspecify.annotations.*).
JSpecify is designed specifically for expressing Java nullness in a way that works consistently across IDEs, static analyzers, and JVM languages such as Kotlin. Adopting JSpecify would improve the clarity and portability of the library’s nullability contracts, particularly for downstream consumers.
Motivation
1. Clearer nullness semantics for libraries
JSpecify defines a precise model for nullness semantics, whereas Jakarta nullability annotations were not originally designed to provide a standardized interpretation across tools.
In practice, Jakarta annotations may be interpreted differently by IDEs, static analyzers, or frameworks. JSpecify instead aims to provide a consistent, tool-agnostic definition of nullness contracts.
JSpecify also fully supports type-use annotations, which allows nullability to be expressed within generic types:
List<@Nullable String>
Map<String, @Nullable Integer>
2. Better interoperability with Kotlin
Kotlin increasingly recognizes JSpecify annotations when determining nullability of Java APIs.
Using JSpecify improves Kotlin callers’ experience by producing more accurate Kotlin types (nullable vs non-nullable) when interacting with this library.
3. Improved static analysis support
Modern static analysis tools (for example Error Prone + NullAway, Checker Framework, etc.) increasingly support JSpecify as the canonical nullness annotation set.
This allows projects to enforce nullness correctness in CI pipelines without tying the library to a specific IDE or vendor annotation set.
4. Library-friendly defaulting model
JSpecify supports a clear default model via @NullMarked, where types are non-null by default and only exceptions require explicit @Nullable.
Example:
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
package com.example.library;
Proposal: Use JSpecify annotations for nullability instead of Jakarta annotations
Summary
This issue proposes migrating the library’s nullability annotations from Jakarta (
jakarta.annotation.*) to JSpecify (org.jspecify.annotations.*).JSpecify is designed specifically for expressing Java nullness in a way that works consistently across IDEs, static analyzers, and JVM languages such as Kotlin. Adopting JSpecify would improve the clarity and portability of the library’s nullability contracts, particularly for downstream consumers.
Motivation
1. Clearer nullness semantics for libraries
JSpecify defines a precise model for nullness semantics, whereas Jakarta nullability annotations were not originally designed to provide a standardized interpretation across tools.
In practice, Jakarta annotations may be interpreted differently by IDEs, static analyzers, or frameworks. JSpecify instead aims to provide a consistent, tool-agnostic definition of nullness contracts.
JSpecify also fully supports type-use annotations, which allows nullability to be expressed within generic types:
2. Better interoperability with Kotlin
Kotlin increasingly recognizes JSpecify annotations when determining nullability of Java APIs.
Using JSpecify improves Kotlin callers’ experience by producing more accurate Kotlin types (nullable vs non-nullable) when interacting with this library.
3. Improved static analysis support
Modern static analysis tools (for example Error Prone + NullAway, Checker Framework, etc.) increasingly support JSpecify as the canonical nullness annotation set.
This allows projects to enforce nullness correctness in CI pipelines without tying the library to a specific IDE or vendor annotation set.
4. Library-friendly defaulting model
JSpecify supports a clear default model via
@NullMarked, where types are non-null by default and only exceptions require explicit@Nullable.Example: