nats.java
nats.java copied to clipboard
Add nullability annotations
Proposed change
Please annotate the API, including return types and parameters, with @javax.annotations.NonNull or @javax.annotations.Nullable as appropriate so that users of the API know what can and can't be null.
Use case
My use case is when using jnats from kotlin, but it applies to any user of jnats. For example, I discovered that io.nats.client.api.KeyValueEntry has a method
public byte[] getValue() {
return value;
}
that allows for the returned byte[] to be null. Kotlin builds nullability into the type system for compile-time checking, and if Java APIs include these annotations, the kotlin compiler can inform the developer better about nullability.
Contribution
No response
@matthewadams We are currently looking at how we can improve integration with Kotlin, and this will make the list.
Have an example of using JetBrains' annotations here: https://github.com/nats-io/nats.java/commit/869012beff5de73eb0715b03f794cf4ec0068494
Tried out javax and jakarta annotations for @NotNull as well, but those didn't seem to be recognized.
Without the @NotNull annotation you need to technically handle the case where entry.operation == null, even if it's not possible to be
Adding JetBrains' @NotNull solves that.
Could be an option to use those.
An alternative that works as well: org.checkerframework:checker-qual using @NonNull.
Maybe this is also an option? https://jspecify.dev/
I support @cbasener and would like to encourage you to migrate your project from JetBrains nullable annotations to JSpecify. https://jspecify.dev/
JSpecify is developed collaboratively by major players across the Java ecosystem, aiming to be the unified, open standard for nullness annotations: i.e. Google (Android, Error Prone, Guava), JetBrains (IDEA, Kotlin), OpenJDK team, Spring, Sonar, etc
Spring 7 (Nov. 2025) uses JSpecify and Uber NullAway for ultimate Null Safety https://spring.io/blog/2025/03/10/null-safety-in-spring-apps-with-jspecify-and-null-away
https://github.com/nats-io/spring-nats/issues/62
If JetBrains is involved, wouldn't it stand to reason that their library will adhere to any collaboration they are part of? Can you please point me to any official statements from JetBrains.
It is unexpectedly hard to find such information in plain sight 🙏😱 I have seen "JetBrains is in JSpecify committee" in newsgroups, YouTube videos, etc. I use IDEA, and it definitely supports JSpecify...
For Kotlin see: https://github.com/JetBrains/kotlin/blob/master/third-party/java8-annotations/org/jspecify/annotations/Nullable.java
For Oracle/OpenJDK: https://mail.openjdk.org/pipermail/valhalla-spec-experts/2022-November/002209.html https://github.com/jspecify/jspecify/wiki/jspecify-faq OpenJDK is a member of our group, and if Java ever one day has null-aware types, the JSpecify standard will be the only reasonable starting point to base it on.
https://jspecify.dev/about/ ^ JetBrains is listed as a member with support in both: Kotlin and IntelliJ IDEA 🤷♀️
The most important: Spring migrates to JSpecify and replaces its own annotations, so the whole Spring infrastructure will eventually migrate to JSpecify.
Lombok supports it :)
JUnit: https://github.com/junit-team/junit-framework/pull/4557
NullAway (see also article about Spring and NullAway): https://github.com/uber/NullAway
For actual migration, you could find useful: https://docs.openrewrite.org/recipes/java/jspecify/migratefromjetbrainsannotations
I'm inclined to make the change, especially since it's basically a search and replace of the import. I don't have to do the effort to put a class wide annotation that covers all non-null. My concern is over semver and I just want to think out loud here. ? We would be changing a dependency. Annoying yes. Breaking? Well if it was when I removed the library with the CVE and used bouncy castle, I didn't care. ? Would we be changing any api? No. What was marked as null/not null before does not change. No signature's change. Intellij users won't have to do anything. Other ide's... I assume that they won't either.
I don't have to do the effort to put a class wide annotation that covers all non-null.
It is a working solution 👍: then the code has unknown nullability (default behavior). Or you can annotate package(s), not individual classes
it's basically a search and replace of the import
Yes in 99% cases
But there are corner cases like Map.@Nullable Entry 😅
I was a long-time user of jsr305 javax.annotation.Nullable, but after some time I find JSpecify type annotations more expressive
Like in List<@Nullable T> → List is not null, elements can be null
Can you please point me to any official statements from JetBrains.
https://www.jetbrains.com/idea/whatsnew/#page__content-jspecify-support--a-major-step-toward-safer-code
🥳🚀