Skip to content

Commit 74ed9dd

Browse files
committed
Provide guidelines for NullAway
Closes spring-projectsgh-34202
1 parent 63acff9 commit 74ed9dd

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

framework-docs/modules/ROOT/pages/core/null-safety.adoc

+38-5
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ to enforce null-safety during build time at application level.
3737
[[null-safety-guidelines]]
3838
== Guidelines
3939

40-
The purpose of this section is to share some guidelines proposed for using JSpecify annotations in the context of
41-
Spring-related libraries or applications.
40+
The purpose of this section is to share some guidelines proposed for specifying explicitly the nullness of Spring-related
41+
libraries or applications.
42+
43+
44+
[[null-safety-guidelines-jpecify]]
45+
=== JSpecify
4246

4347
The key points to understand is that by default, the nullness of types is unknown in Java, and that non-null type
4448
usages are by far more frequent than nullable ones. In order to keep codebases readable, we typically want to define
@@ -98,11 +102,40 @@ https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html[`@NonNull`]
98102
https://jspecify.dev/docs/api/org/jspecify/annotations/NullUnmarked.html[`@NullUnmarked`] should rarely be needed for
99103
typical use cases.
100104

101-
The {spring-framework-api}/lang/Contract.html[@Contract] annotation in the `org.springframework.lang` package
105+
[[null-safety-guidelines-nullaway]]
106+
=== NullAway
107+
108+
=== Configuration
109+
110+
The recommended configuration is:
111+
112+
- `NullAway:OnlyNullMarked=true` in order to perform nullness checks only for packages annotated with `@NullMarked`.
113+
- `NullAway:CustomContractAnnotations=org.springframework.lang.Contract` which makes NullAway aware of the
114+
{spring-framework-api}/lang/Contract.html[@Contract] annotation in the `org.springframework.lang` package which
102115
can be used to express complementary semantics to avoid non-relevant null-safety warnings in your codebase.
103116

104-
NOTE: Complementary to nullness annotations, the {spring-framework-api}/lang/CheckReturnValue.html[@CheckReturnValue]
105-
annotation in the `org.springframework.lang` package can be used to specify that the method return value must be used.
117+
A good example of `@Contract` benefits is
118+
{spring-framework-api}/util/Assert.html#notNull(java.lang.Object,java.lang.String)[`Assert#notnull`] which is annotated
119+
with `@Contract("null, _ -> fail")`. With the configuration above, NullAway will understand that after a successful
120+
invocation, the value passed as a parameter is not null.
121+
122+
=== Warnings suppression
123+
124+
There are a few valid use cases where NullAway will wrongly detect nullness problems. In such case, it is recommended
125+
to suppress related warnings and to document the reason:
126+
127+
- `@SuppressWarnings("NullAway.Init")` at field, constructor or class level can be used to avoid unnecessary warnings
128+
due to the lazy initialization of fields, for example due to a class implementing
129+
{spring-framework-api}/beans/factory/InitializingBean.html[`InitializingBean`].
130+
- `@SuppressWarnings("NullAway") // Dataflow analysis limitation` can be used when NullAway dataflow analysis is not
131+
able to detect that the path involving a nullness problem will never happen.
132+
- `@SuppressWarnings("NullAway") // Lambda` can be used when NullAway does not take into account assertions performed
133+
outside of a lambda for the code path within the lambda.
134+
- `@SuppressWarnings("NullAway") // Reflection` can be used for some reflection operations that are known returning
135+
non-null values even if that can't be expressed by the API.
136+
- `@SuppressWarnings("NullAway") // Well-known map keys` can be used when `Map#get` invocations are done with keys known
137+
to be present and non-null related values inserted previously.
138+
106139

107140
[[null-safety-migrating]]
108141
== Migrating from Spring null-safety annotations

0 commit comments

Comments
 (0)