Polishing
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details

This commit is contained in:
Juergen Hoeller 2025-07-10 20:05:47 +02:00
parent e9c402cd0f
commit 22a23322f3
2 changed files with 35 additions and 33 deletions

View File

@ -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).

View File

@ -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} -