Replace JSR 305 based nullness annotations with JSpecify annotations #219

Open
opened 2025-12-30 01:22:22 +01:00 by adam · 2 comments
Owner

Originally created by @odenix on GitHub (Oct 16, 2024).

https://github.com/jspecify/jspecify
https://jspecify.dev/

Motivation:

  • JSR 305 has been dead for a decade.
  • JSR 305 has many known issues: incompatible with Java module system, unclear semantics, no official support for generics, etc.
  • The common practice of using JSR 305 as meta-annotations to avoid a transitive dependency on JSR 305 has more downsides than upsides: bogus compiler warnings about missing JSR 305 classes in Pkl and upstream (!) builds, IDEs can’t resolve JSR 305 classes when browsing Pkl codebase in upstream projects, upstream projects require extra configuration (!) to recognize Pkl’s nullness annotations.

Risk assessment:

  • JSpecify is a tiny library that contains a handful of annotation types and doesn’t have any dependencies.
  • JSpecify recently had its 1.0.0 release, which comes with an eternal backwards compatibility guarantee.
  • JSpecify 1.0.0 already has decent adoption.
    Spring Framework will switch from JSR 305 to JSpecify in its next major release (7.0).
    Google’s internal Guava version has been using JSpecify for years.
  • JSpecify is well supported by IntelliJ and Kotlin (since 1.5.20).

Changes:

  • Replace Pkl nullness annotations, which are meta-annotated by JSR 305 annotations, with JSpecify nullness annotations.
  • Declare a regular dependency on JSpecify (no more “compileOnly” trickery). Projects that cannot tolerate a JSpecify dependency can exclude JSpecify in their build.

Result:

  • Better nullness checks by IntelliJ and kotlinc.
  • No more bogus compiler warnings about missing JSR 305 classes.
  • No more IDE errors for unresolved JSR 305 classes.
  • Upstream projects recognize nullness annotations in Pkl APIs without any extra configuration.
  • Nullness annotations can be used in all Pkl subprojects, including those that don’t depend on pkl-core.
  • Compatibility with Java module system (prerequisite for shipping Java module descriptors for Pkl libraries).

A future Java version will likely support nullable types (JEP Draft). Until that Java version becomes Pkl’s baseline, JSpecify will remain the best way to handle nullness in Pkl’s Java codebase.

Originally created by @odenix on GitHub (Oct 16, 2024). https://github.com/jspecify/jspecify https://jspecify.dev/ Motivation: * JSR 305 has been dead for a decade. * JSR 305 has many known issues: incompatible with Java module system, unclear semantics, no official support for generics, etc. * The common practice of using JSR 305 as meta-annotations to avoid a transitive dependency on JSR 305 has more downsides than upsides: bogus compiler warnings about missing JSR 305 classes in Pkl and upstream (!) builds, IDEs can’t resolve JSR 305 classes when browsing Pkl codebase in upstream projects, upstream projects require extra configuration (!) to recognize Pkl’s nullness annotations. Risk assessment: * JSpecify is a tiny library that contains a handful of annotation types and doesn’t have any dependencies. * JSpecify recently had its 1.0.0 release, which comes with an eternal backwards compatibility guarantee. * JSpecify 1.0.0 already has decent [adoption](https://central.sonatype.com/artifact/org.jspecify/jspecify/dependents). Spring Framework will switch from JSR 305 to JSpecify in its next major release (7.0). Google’s internal Guava version has been using JSpecify for years. * JSpecify is well supported by IntelliJ and Kotlin (since 1.5.20). Changes: * Replace Pkl nullness annotations, which are meta-annotated by JSR 305 annotations, with JSpecify nullness annotations. * Declare a regular dependency on JSpecify (no more “compileOnly” trickery). Projects that cannot tolerate a JSpecify dependency can exclude JSpecify in their build. Result: * Better nullness checks by IntelliJ and kotlinc. * No more bogus compiler warnings about missing JSR 305 classes. * No more IDE errors for unresolved JSR 305 classes. * Upstream projects recognize nullness annotations in Pkl APIs without any extra configuration. * Nullness annotations can be used in all Pkl subprojects, including those that don’t depend on pkl-core. * Compatibility with Java module system (prerequisite for shipping Java module descriptors for Pkl libraries). A future Java version will likely support nullable types ([JEP Draft](https://openjdk.org/jeps/8303099)). Until that Java version becomes Pkl’s baseline, JSpecify will remain the best way to handle nullness in Pkl’s Java codebase.
Author
Owner

@bioball commented on GitHub (Oct 17, 2024):

Agree; would be good to move to JSpecify. Happy to accept a PR for this.

@bioball commented on GitHub (Oct 17, 2024): Agree; would be good to move to JSpecify. Happy to accept a PR for this.
Author
Owner

@odenix commented on GitHub (Oct 17, 2024):

I’ll send a PR after 0.27 is out.

@odenix commented on GitHub (Oct 17, 2024): I’ll send a PR after 0.27 is out.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/pkl#219