Polishing
This commit is contained in:
parent
e9c402cd0f
commit
22a23322f3
|
@ -6,32 +6,34 @@ annotated with https://jspecify.dev/docs/start-here/[JSpecify] annotations to de
|
||||||
fields, and related type usages. Reading the https://jspecify.dev/docs/user-guide/[JSpecify user guide] is highly
|
fields, and related type usages. Reading the https://jspecify.dev/docs/user-guide/[JSpecify user guide] is highly
|
||||||
recommended in order to get familiar with those annotations and semantics.
|
recommended in order to get familiar with those annotations and semantics.
|
||||||
|
|
||||||
The primary goal of this null-safety arrangement is to prevent a `NullPointerException` from being thrown at runtime via build
|
The primary goal of this null-safety arrangement is to prevent a `NullPointerException` from being thrown at
|
||||||
time checks and to use explicit nullability as a way to express the possible absence of value. It is useful in both
|
runtime via build time checks and to use explicit nullability as a way to express the possible absence of value.
|
||||||
Java by leveraging some tooling (https://github.com/uber/NullAway[NullAway] or IDEs supporting JSpecify annotations
|
It is useful in both Java by leveraging some tooling (https://github.com/uber/NullAway[NullAway] or IDEs supporting
|
||||||
such as IntelliJ IDEA) and Kotlin where JSpecify annotations are automatically translated to
|
JSpecify annotations such as IntelliJ IDEA) and Kotlin where JSpecify annotations are automatically translated to
|
||||||
{kotlin-docs}/null-safety.html[Kotlin's null safety].
|
{kotlin-docs}/null-safety.html[Kotlin's null safety].
|
||||||
|
|
||||||
The {spring-framework-api}/core/Nullness.html[`Nullness` Spring API] can be used at runtime to detect the nullness of a
|
The {spring-framework-api}/core/Nullness.html[`Nullness` Spring API] can be used at runtime to detect the
|
||||||
type usage, a field, a method return type, or a parameter. It provides full support for JSpecify annotations,
|
nullness of a type usage, a field, a method return type, or a parameter. It provides full support for
|
||||||
Kotlin null safety, and Java primitive types, as well as a pragmatic check on any `@Nullable` annotation (regardless of the
|
JSpecify annotations, Kotlin null safety, and Java primitive types, as well as a pragmatic check on any
|
||||||
package).
|
`@Nullable` annotation (regardless of the package).
|
||||||
|
|
||||||
|
|
||||||
[[null-safety-libraries]]
|
[[null-safety-libraries]]
|
||||||
== Annotating libraries with JSpecify annotations
|
== Annotating libraries with JSpecify annotations
|
||||||
|
|
||||||
As of Spring Framework 7, the Spring Framework codebase leverages JSpecify annotations to expose null-safe APIs and
|
As of Spring Framework 7, the Spring Framework codebase leverages JSpecify annotations to expose null-safe APIs
|
||||||
to check the consistency of those nullability declarations with https://github.com/uber/NullAway[NullAway] as part of
|
and to check the consistency of those nullability declarations with https://github.com/uber/NullAway[NullAway]
|
||||||
its build. It is recommended for each library depending on Spring Framework and Spring portfolio projects, as
|
as part of its build. It is recommended for each library depending on Spring Framework and Spring portfolio projects,
|
||||||
well as other libraries related to the Spring ecosystem (Reactor, Micrometer, and Spring community projects), to do the
|
as well as other libraries related to the Spring ecosystem (Reactor, Micrometer, and Spring community projects),
|
||||||
same.
|
to do the same.
|
||||||
|
|
||||||
|
|
||||||
[[null-safety-applications]]
|
[[null-safety-applications]]
|
||||||
== Leveraging JSpecify annotations in Spring applications
|
== Leveraging JSpecify annotations in Spring applications
|
||||||
|
|
||||||
Developing applications with IDEs that support nullness annotations will provide warnings in Java and errors in Kotlin
|
Developing applications with IDEs that support nullness annotations will provide warnings in Java and errors in
|
||||||
when the nullability contracts are not honored, allowing Spring application developers to refine their null handling to
|
Kotlin when the nullability contracts are not honored, allowing Spring application developers to refine their
|
||||||
prevent a `NullPointerException` from being thrown at runtime.
|
null handling to prevent a `NullPointerException` from being thrown at runtime.
|
||||||
|
|
||||||
Optionally, Spring application developers can annotate their codebase and use build plugins like
|
Optionally, Spring application developers can annotate their codebase and use build plugins like
|
||||||
https://github.com/uber/NullAway[NullAway] to enforce null-safety at the application level during build time.
|
https://github.com/uber/NullAway[NullAway] to enforce null-safety at the application level during build time.
|
||||||
|
@ -47,11 +49,11 @@ Spring-related libraries or applications.
|
||||||
|
|
||||||
==== Defaults to non-null
|
==== Defaults to non-null
|
||||||
|
|
||||||
A key point to understand is that the nullness of types is unknown by default in Java and that non-null type
|
A key point to understand is that the nullness of types is unknown by default in Java and that non-null type usage
|
||||||
usage is by far more frequent than nullable usage. In order to keep codebases readable, we typically want to define
|
is by far more frequent than nullable usage. In order to keep codebases readable, we typically want to define by
|
||||||
by default that type usage is non-null unless marked as nullable for a specific scope. This is exactly the purpose of
|
default that type usage is non-null unless marked as nullable for a specific scope. This is exactly the purpose
|
||||||
https://jspecify.dev/docs/api/org/jspecify/annotations/NullMarked.html[`@NullMarked`] which is typically set in Spring
|
of https://jspecify.dev/docs/api/org/jspecify/annotations/NullMarked.html[`@NullMarked`] which is typically set
|
||||||
projects at the package level via a `package-info.java` file, for example:
|
in Spring projects at the package level via a `package-info.java` file, for example:
|
||||||
|
|
||||||
[source,java,subs="verbatim,quotes",chomp="-packages",fold="none"]
|
[source,java,subs="verbatim,quotes",chomp="-packages",fold="none"]
|
||||||
----
|
----
|
||||||
|
@ -133,6 +135,7 @@ The Java specification also enforces that annotations defined with `@Target(Elem
|
||||||
- `Cache.@Nullable ValueWrapper`
|
- `Cache.@Nullable ValueWrapper`
|
||||||
- `jakarta.validation.@Nullable Validator`
|
- `jakarta.validation.@Nullable Validator`
|
||||||
|
|
||||||
|
|
||||||
[[null-safety-guidelines-nullaway]]
|
[[null-safety-guidelines-nullaway]]
|
||||||
=== NullAway
|
=== NullAway
|
||||||
|
|
||||||
|
@ -146,9 +149,9 @@ The recommended configuration is:
|
||||||
can be used to express complementary semantics to avoid irrelevant warnings in your codebase.
|
can be used to express complementary semantics to avoid irrelevant warnings in your codebase.
|
||||||
|
|
||||||
A good example of the benefits of a `@Contract` declaration can be seen with
|
A good example of the benefits of a `@Contract` declaration can be seen with
|
||||||
{spring-framework-api}/util/Assert.html#notNull(java.lang.Object,java.lang.String)[`Assert.notNull()`] which is annotated
|
{spring-framework-api}/util/Assert.html#notNull(java.lang.Object,java.lang.String)[`Assert.notNull()`]
|
||||||
with `@Contract("null, _ -> fail")`. With that contract declaration, NullAway will understand that the value passed as a
|
which is annotated with `@Contract("null, _ -> fail")`. With that contract declaration, NullAway will understand
|
||||||
parameter cannot be null after a successful invocation of `Assert.notNull()`.
|
that the value passed as a parameter cannot be null after a successful invocation of `Assert.notNull()`.
|
||||||
|
|
||||||
Optionally, it is possible to set `NullAway:JSpecifyMode=true` to enable
|
Optionally, it is possible to set `NullAway:JSpecifyMode=true` to enable
|
||||||
https://github.com/uber/NullAway/wiki/JSpecify-Support[checks on the full JSpecify semantics], including annotations on
|
https://github.com/uber/NullAway/wiki/JSpecify-Support[checks on the full JSpecify semantics], including annotations on
|
||||||
|
@ -160,8 +163,8 @@ generates no warning with the recommended configuration mentioned previously in
|
||||||
|
|
||||||
==== Warnings suppression
|
==== Warnings suppression
|
||||||
|
|
||||||
There are a few valid use cases where NullAway will incorrectly detect nullability problems. In such cases, it is recommended
|
There are a few valid use cases where NullAway will incorrectly detect nullability problems. In such cases,
|
||||||
to suppress related warnings and to document the reason:
|
it is recommended to suppress related warnings and to document the reason:
|
||||||
|
|
||||||
- `@SuppressWarnings("NullAway.Init")` at field, constructor, or class level can be used to avoid unnecessary warnings
|
- `@SuppressWarnings("NullAway.Init")` at field, constructor, or class level can be used to avoid unnecessary warnings
|
||||||
due to the lazy initialization of fields – for example, due to a class implementing
|
due to the lazy initialization of fields – for example, due to a class implementing
|
||||||
|
@ -172,8 +175,8 @@ able to detect that the path involving a nullability problem will never happen.
|
||||||
outside of a lambda for the code path within the lambda.
|
outside of a lambda for the code path within the lambda.
|
||||||
- `@SuppressWarnings("NullAway") // Reflection` can be used for some reflection operations that are known to return
|
- `@SuppressWarnings("NullAway") // Reflection` can be used for some reflection operations that are known to return
|
||||||
non-null values even if that cannot be expressed by the API.
|
non-null values even if that cannot be expressed by the API.
|
||||||
- `@SuppressWarnings("NullAway") // Well-known map keys` can be used when `Map#get` invocations are performed with keys that are known
|
- `@SuppressWarnings("NullAway") // Well-known map keys` can be used when `Map#get` invocations are performed with keys
|
||||||
to be present and when non-null related values have been inserted previously.
|
that are known to be present and when non-null related values have been inserted previously.
|
||||||
- `@SuppressWarnings("NullAway") // Overridden method does not define nullability` can be used when the superclass does
|
- `@SuppressWarnings("NullAway") // Overridden method does not define nullability` can be used when the superclass does
|
||||||
not define nullability (typically when the superclass comes from an external dependency).
|
not define nullability (typically when the superclass comes from an external dependency).
|
||||||
- `@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075` can be used when NullAway is not able to detect type variable nullness in generic methods.
|
- `@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075` can be used when NullAway is not able to detect type variable nullness in generic methods.
|
||||||
|
@ -208,7 +211,6 @@ with JSpecify annotations.
|
||||||
- For method return types, instead of `@Nullable public String method()` with Spring annotations, use
|
- For method return types, instead of `@Nullable public String method()` with Spring annotations, use
|
||||||
`public @Nullable String method()` with JSpecify annotations.
|
`public @Nullable String method()` with JSpecify annotations.
|
||||||
|
|
||||||
Also, with JSpecify, you do not need to specify `@NonNull` when overriding a type usage annotated with `@Nullable` in the
|
Also, with JSpecify, you do not need to specify `@NonNull` when overriding a type usage annotated with `@Nullable`
|
||||||
super method to "undo" the nullable declaration in null-marked code. Just declare it unannotated, and the null-marked
|
in the super method to "undo" the nullable declaration in null-marked code. Just declare it unannotated, and the
|
||||||
defaults will apply (type usage is considered non-null unless explicitly annotated as nullable).
|
null-marked defaults will apply (type usage is considered non-null unless explicitly annotated as nullable).
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Hibernate-specific support classes, integrated with JPA.
|
* Hibernate-specific support classes, integrated with JPA.
|
||||||
*
|
*
|
||||||
* <p>Contains Hibernate-specific setup options as an alternative to JPA bootstrapping,
|
* <p>Contains Hibernate-specific setup options as an alternative to JPA bootstrapping,
|
||||||
* primarily for use with Hibernate's native {@code sessionFactory.getCurrentSession()}
|
* primarily for use with Hibernate's native {@code SessionFactory#getCurrentSession()}
|
||||||
* but potentially also for JPA repositories or mixed use of native Hibernate and JPA.
|
* but potentially also for JPA repositories or mixed use of native Hibernate and JPA.
|
||||||
*
|
*
|
||||||
* <p>As of Spring Framework 7.0, this package supersedes {@code orm.hibernate5} -
|
* <p>As of Spring Framework 7.0, this package supersedes {@code orm.hibernate5} -
|
||||||
|
|
Loading…
Reference in New Issue