Affects: 5.0.10


Summary

The JSR305 @CheckForNull annotation should be treated equivalently to the Spring @org.springframework.lang.Nullable annotation. It is supposed to have the same semantic meaning: users of a variable should be checked for nullness before it is used, because it is intended to sometimes have a null value; and null is a valid and expected value for clients of the code to pass.

Details

The specific instance of this encountered was using constructor injection. A "Nullable"-like annotation can be applied to constructor parameter to tell Spring that the parameter is optional (if it can't be injected, then null is passed for it, instead of failing).

While adding the @javax.annotation.Nullable from Findbugs JSR305 v3.0.1 does work to indicate optional parameters to Spring, the @javax.annotation.CheckForNull does not work.

Now the naming of JSR305 @Nullable and @CheckForNull is very confusing, so take care. @CheckForNull is actually the most correct annotation in this case, due to how JSR305 defines @CheckForNull (stronger) and @Nullable (weaker).

Quick reference:

"The annotated element could be null under some circumstances. [...] This annotation is useful mostly for overriding a Nonnull annotation. [...] Use CheckForNull to indicate that the element value should always be checked for a null value." JSR305 Nullable.java

"The annotated element might be null, and uses of the element should check for null." JSR305 CheckForNull.java

Minimal Complete Verifiable Example

See https://github.com/cdbennett/spring-checkfornull-test for a complete example illustrating the problem.

Comment From: jhoeller

While technically this would be a semantic match, JSR-305 is being phased out since it was never a properly accepted specification to begin with. For that reason, we do not intend to build specific integration with it, other than the meta-annotations on our own set of nullability annotations (which we keep for tooling integration for the time being).

So we primarily focus on our own set of annotations including org.springframework.lang.Nullable and leniently tolerate same-named annotations from other packages of which there are plenty out there. In a way, we treat "nullable" as a sort of keyword, caring more for readable wording of the overall method signature than strict semantics.