common-annotations-api icon indicating copy to clipboard operation
common-annotations-api copied to clipboard

`@Nullable` and `Nonnull` VS jspecify

Open hantsy opened this issue 11 months ago • 3 comments

jspecify is more popular and gets better community tools support today, the next Spring 7.0 has already migrated to jspecify to check the field/method param/return type nullable.

In the current Jakarta Annotations, the @Nullable and NonNull are extracted from JSR305. Jspecify provides more features and compatibility.

With wider tool support when using Jspecify, we can generate static analysis reports at compile time。

If we keep the existing @Nullable/@Nonnull in Jakarta EE, can we generate analysis results at deployment time?

hantsy avatar Dec 28 '24 07:12 hantsy

My comments:

  • It makes sense to mark Nullable and Nonull annotations as deprecated, in favor of JSpecify annotations, as they are only to be used in IDEs and build tools, other Jakarta EE specifications don't depend on them
  • Jakarta EE cannot depend on JSpecify, as it's not a JCP or Jakarta EE spec. Jakarta EE can depend only on JCP and Jakarta EE specs right now
  • Jakarta EE cannot require that implementations validate JSpecify annotations. It can recommend it and implementations can do it optionally, even now, without doing anything in Jakarta EE. I don't understand how Spring "migrated" to JSpecify annotations, because Spring is not an IDE or a build tool

OndroMih avatar Dec 28 '24 08:12 OndroMih

Now I found this: https://groups.google.com/g/jspecify-discuss/c/wuzseVstInk?pli=1 - it seems that Spring code base and API migrated to JSpecify annotations. Does any Jakarta EE API use the JCP or Jakarta EE nullable/nonnull annotations? If yes, I believe it's more practical to replace them with JSpecify annotations, without any requirement that Jakarta EE implementations have to support them. If annotations are not on the classpath, JVM simply ignores them.

@tomas-langer , @m0mus , I see you added these annotations to Jakarta Annotations in https://github.com/jakartaee/common-annotations-api/pull/90, are they used in some other Jakarta APIs?

OndroMih avatar Dec 28 '24 08:12 OndroMih

I don't understand how Spring "migrated" to JSpecify annotations, because Spring is not an IDE or a build tool

https://github.com/sdeleuze/spring-framework/commit/62daae08d3fb4f784a33acbcf4e76ebc816760ac

Spring adds nullaway and errprone to check the nullability and generate static analysis at build time. All Spring APIs are marked with essential @Nullalbe constraints, which make the API more robust. For developers, it will assist API callers in avoiding unnecessary NPE, and also easier to interact with Kotlin, etc.

If we keep using the existing @Nullable, we also should add the nullable constraints to all Jakarta EE APIs.

hantsy avatar Dec 28 '24 08:12 hantsy

Persistence NG tries to add Nonnull/Nullable to APIs, here is my comment on Persistence: https://github.com/jakartaee/persistence/pull/726#issuecomment-3096729372

@OndroMih Personally, I would like to deprecate these annotations, and use JSpecify directly to get IDE and build time support.

hantsy avatar Jul 21 '25 13:07 hantsy

It makes sense to mark Nullable and Nonnull annotations as deprecated, in favor of JSpecify annotations, as they are only to be used in IDEs and build tools, other Jakarta EE specifications don't depend on them

Please do not mark these annotations as deprecated, since we are proposing to make use of them in Jakarta Persistence 4.0. See:

  • https://github.com/jakartaee/persistence/issues/614
  • https://github.com/jakartaee/persistence/issues/725

Jakarta EE cannot depend on JSpecify, as it's not a JCP or Jakarta EE spec. Jakarta EE can depend only on JCP and Jakarta EE specs right now

This is 100% correct. Jakarta specifications can't depend on random open source libraries. Therefore, Nullable and Nonnull are our only option here.

gavinking avatar Jul 22 '25 06:07 gavinking

This is 100% correct. Jakarta specifications can't depend on random open source libraries. Therefore, Nullable and Nonnull are our only option here.

It is a good reason, but currently these annotations in Jakarta Common Annotations lack tools support(IDE, and build tools) like JSpecify.

hantsy avatar Jul 22 '25 08:07 hantsy

currently these annotations in Jakarta Common Annotations lack tools support(IDE, and build tools) like JSpecify.

That's not really true; they work perfectly well in IntelliJ.

gavinking avatar Jul 22 '25 09:07 gavinking

+1 for deprecating jakarta's @Nullable:

  • Jakarta's nullable does not work with generics. One can't use jakarta's annotation like List<@Nullable String>. I have annotated Apache Calcite and pgjdbc with machine-verifiable nullability, and the support for List<@Nullable was very helpful in both projects.
  • Jakarta's nullable does not have a spec for marking class/package/module as null marked, so it is hard to tell what does "unmarked" code mean under Jakarta nullability
  • Users might accidentally treat Jakarta's @Nullable as a way to go because, well, it is under Jakarta name. Here's such an example: https://github.com/phax/ph-commons/issues/54
  • Jakarta's annotations has problematic license, and it does not work well for a general-purpose library. For instance, the Apache Software Foundation does not like EPL/GPL licenses, see https://www.apache.org/legal/resolved.html#category-b. It does not necessarily mean you should relicense, however, jspecify goes under Apache 2.0 license which is much more permissive than jakarta's nullability annotation.

This is 100% correct. Jakarta specifications can't depend on random open source libraries

Right you are. Frankly, https://jspecify.dev/about/ does not look like a random open-source library. There are many great companies working on jspecify, and they did a significant analysis for making Java nullability workable: https://github.com/jspecify/jspecify/issues, https://github.com/jspecify/jspecify/pulls.

Your mileage may vary, however, judging by the amount of investment, and judging by the usability I would consider jspecify's @Nullable to be in much better position rather than Jakarta's @Nullable. I don't mean Jakarta is bad. I just mean jspecify's @Nullable is much more developed than the one from Jakarta.


Would you please reconsider and deprecate Jakarta's @Nullable and @Nonnull? If you absolutely want keeping @Nullable and @Nonnull, could you please add a clarification javadoc comment that would explain the key meaning for the annotation when compared with the others?

vlsi avatar Nov 03 '25 10:11 vlsi

Would you please reconsider and deprecate Jakarta's @Nullable and @Nonnull? If you absolutely want keeping @Nullable and @Nonnull, could you please add a clarification javadoc comment that would explain the key meaning for the annotation when compared with the others?

Currently, the Jakarta's Nullable/Nonnull is not widely used in all Jakarta specs. I only noticed Persistence tried to adopt it at the moment.

Deprecate it and free developers to use the mature JSpecify or other tools.

hantsy avatar Nov 04 '25 01:11 hantsy