adoption - jspecify/jspecify GitHub Wiki

Should you adopt JSpecify annotations?

Short answer

It's probably a little soon right now, but as of our 1.0 jar release... maybe.

How frozen is the JAR?

As of JSpecify 0.3, it's now extremely unlikely there will be any compilation-breaking change to the four annotation interfaces (exception noted next). We're not moving, renaming, or removing anything anymore. So once your tools recognize them at all, then switching probably couldn't hurt much.

There is one very minor exception: it is possible @Target(METHOD) could be removed from @NullMarked and @NullUnmarked. Of course, you would be immune to that change if you simply avoid using them on methods. But even if you do, the trouble this causes should be minimal.

Why is it only "0.3"?

It's really more like 0.9.

The specification is still evolving, at the edge cases. This means that if you used a 100% spec-conformant tool as you annotated your large codebase, then a future spec change might mean that in a few cases you had to go back and remove a @Nullable here or add a @NonNull there. Any change this would force on you would very likely be small and/or automatable. We're not going to suddenly decide that nullable means non-null.

But tools aren't 100% conforming to this specification yet anyway. They're evolving toward it, so you may already have small adjustments to make over time. The spec is a bit of a moving target, but probably not moving nearly as much as the tool support is moving toward it.

Should my internal (non-public) codebase adopt these annotations now?

(If your library has Kotlin clients, see the Kotlin section below instead.)

If you already use nullness analysis, check if your tool even recognizes org.jspecify.annotations (note: not org.jspecify.nullness) annotations at all, or if you can configure it to. If not, it would be premature.

If it is, switching to our annotations shouldn't really make anything worse. True, dvelopers who click through to our Javadoc might see specific claims that their tools probably don't fully adhere to yet. But the docs of the other annotations don't go into much detail at all, so our details will probably help more than hurt.

Should my library adopt these annotations now?

(If your library has Kotlin clients, see the Kotlin section below instead.)

Here, a "library" means any API with clients that you can't update yourself. This could be an internal API with a few too many users, or a publicly released API with any real users at all.

Your users who "care a lot" about nullness already (e.g. have their builds actually break on nullness findings) can be affected. If you're already using a different annotations artifact, it would be fine to wait a bit before switching, while those tools catch up. If you're not, it probably doesn't hurt to start with JSpecify from the beginning; some users might just not get the value from it immediately.

The previous section of this page applies as well.

What's the Kotlin situation?

JSpecify 0.3 finalized the package name, org.jspecify.annotations. You need to use Kotlin 1.8.20 or later for it to recognize the new location.

When Kotlin detects nullness mismatches as a result of JSpecify annotations, it currently produces only warnings by default. For some other kinds of annotations, it produces errors. You might consider warnings to be better than errors or worse than errors. For example, warnings can be good for a library that is just becoming annotated; errors can be good for a library that has already been annotated. (Users can always configure Kotlin's behavior through the -Xjspecify-annotations=strict flag.)

Kotlin doesn't recognize @NonNull or @NullUnmarked yet.

Is this safe, when your specification will keep shifting from now until 1.0?

The heart of our project has been to nail down the meanings of the annotations with great precision, so you can annotate without regard to which tools will be used. In this sense the JSpecify standard will continue evolving until 1.0, which might concern you.

Your analysis tools will also be progressing toward JSpecify conformance on widely varying schedules. So if you or your clients use nullness analysis "aggressively", you might periodically have to make some annotation adjustments.

However, this same problem probably exists no matter which actual JAR of annotations you're using. So we don't believe it should represent a barrier to adopting the annotations.

Why adopt now at all, then?

There's no specific rush, of course.

But the main thing standing between us and a 1.0 spec is collecting quality real-world feedback from the community. And while feedback of the sort "I thought about this, and here's what I think" is acceptable, "I tried this, and this is what happened" is far more helpful. For that purpose please use our reference checker for now.

So, the more of you who are willing to take the small risks described, the sooner 1.0 will be here!