Defining nullability of some API like EnvironmentCapable
or ConditionContext causes issues in Spring Boot because
in the context where they are used, it is known for sure
they will return non-null values even if their API can in
other context return null values.
It is better in this case for both Java and Kotlin to
not define at all the nullabity of such API.
In practice, this is achieved by removing the package level
@NonNullApi annotation and adding it only on the
relevant classes.
Issue: SPR-15540
This commit makes Spring @Nullable annotation leveraging
JSR 305 @TypeQualifierNickname + @Nonnull(when= When.MAYBE)
instead of directly using @javax.annotation.Nullable which
seems not designed to be used as a meta-annotation.
It also removes @TypeQualifierDefault since the purpose of
this annotation when applied at method level is to only
change return value nullability, not parameters one.
Issue: SPR-15540
This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.
In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.
@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.
In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.
Issue: SPR-15540
Starting with removing a package cycle on the use of
ResponseStatusException in the codec package, this commit generally
refines codec exception handling.
The new [Encoding|Decoding]Exception mirror the existing
HttpMessageNot[Readable|Writable]Exception and are used similarly
especially to differentiate betwen 400 and 500 errors when parsing
server request body content.
The commit also aligns some of the exception handling of JSON and XML
on the WebFlux side with that on the Spring MVC side.
Issue: SPR-15516
Update `SpringFactoriesLoader` to cache property file loads. This helps
reduce the number of garbage objects created as each load uses an 8K
char buffer.
Issue: SPR-15509
This commit introduces a `writableChannel()` method to
`WritableResource`, defaulting to `Channels.newChannel`, but with
overrides for file-based resources.
- Fixed AnnotationUtils.getValue() operation to ensure it re-throws AnnotationConfigurationException instead of swallowing it (as it is done in few other operations in AnnotationUtils)
- Added test
- Removed unnecessary '@SuppressWarnings("unchecked")'
Includes revised Log methods in log level order, with consistent delegation of fatal->error for log level checks in SLF4J and JUL, a JavaUtilDelegate for defensive access to java.logging on JDK 9, support for LogRecord message objects, as well as revised log setup recommendations.
Issue: SPR-15453
Issue: SPR-14512
This commit adds support for reactive library types to be returned
directly from controller methods adapting them either to a
ResponseBodyEmitter (streaming) or DeferredResult (non-streaming).
The reactive libraries supported are the ones that can adapted to a
Reactive Streams Publisher through the ReactiveAdapterRegistry.
Issue: SPR-15365
Follow-up to:
3d68c496f1
StringDecoder can be created in text-only vs "*/*" mode which in turn
allows a more intuitive order of client side decoders, e.g. SSE does
not have to be ahead of StringDecoder.
The commit also explicitly disables String from the supported types in
Jackson2Decoder leaving it to the StringDecoder in "*/*" mode which
comes after. This does not change the current arrangement since the
the StringDecoder ahead having "*/*" picks up JSON content just the
same.
From a broader perspective this change allows any decoder to deal with
String if it wants to after examining the content type be it the SSE
or another, custom decoder. For Jackson there is very little value in
decoding to String which works only if the output contains a single
JSON string but will fail to parse anything else (JSON object/array)
while StringDecoder in "*/*" mode will not fail.
Issue: SPR-15374
CharSequenceEncoder now supports all MIME types, however since encoding
Flux<String> can overlap with other encoders (e.g. SSE) there are now
two ways to create a CharSequenceEncoder -- with support for text/plain
only or with support for any MIME type.
In WebFlux configuration we insert one CharSequenceEncoder for
text/plain (as we have so far) and a second instance with support for
any MIME type at the very end.
Issue: SPR-15374
Support for flushing in EncoderHttpMessageWriter is now driven from a
configurable list of "streaming" media types with the list including
"application/stream+json" by default.
As a result Jackson2ServerHttpMessageWriter is no longer needed.
Currently the BOM versions are:
* reactor-core 3.0.6.BUILD-SNAPSHOT
* reactor-netty 0.6.2.BUILD-SNAPSHOT
This commit fixes as well a few deprecations in reactor-core.
This commit adds an overloaded DataBufferUtils.read method that operates
on a AsynchronousFileChannel (as opposed to a ReadableByteChannel, which
already existed). This commit also uses said method in the Resource
encoders, if the Resource is a file.
This commit *adds* the "intercepted" headers to the ClientHttpRequest,
as opposed to replacing them, which is what happened before this commit.
Issue: SPR-15166
Prior to this commit, the org.springframework.tests.Assume class could
fail to load resulting in a NoClassDefFoundError if parsing of the
'testGroups' system property failed. This is because the parsing took
place while initializing a static field.
This commit addresses this issue by moving the 'testGroups' system
property lookup to a dedicated method that is lazily invoked upon
demand instead of eagerly when loading the Assume class itself.
In addition, when an error occurs, TestGroup.parse() now logs the
complete original value of the supplied test groups string instead of
potentially omitting the "all-" prefix. This results in more
informative error messages similar to the following.
java.lang.IllegalStateException: Failed to parse 'testGroups' system
property: Unable to find test group 'bogus' when parsing testGroups
value: 'all-bogus'. Available groups include:
[LONG_RUNNING,PERFORMANCE,JMXMP,CI]
Issue: SPR-15163
This commit adds a DataBuffer Encoder and Decoder, and uses it in
the annotation-based processing model.
Note that these codecs are not used in the functional processing model,
since the BodyInserter/BodyExtractor already have methods for
writing/reading DataBuffers.
Issue: SPR-15148
The recent refactoring lead to
java.lang.NoClassDefFoundError: io/reactivex/Completable
where only RxJava 1 is in the classpath. Most likely due to the
lack of prefix in Completable::complete with rx package to avoid
the RxJava 2 reference.
Simplify getAdapterFrom/To into a single getAdapter method that looks
for an exact match by type first and then isAssignableFrom.
Also expose shortcut methods in ReactiveAdapter to minimize the need
for access to the ReactiveTypeDescriptor.
Issue: SPR-14902
The ReactiveAdapterRegistry now detects the presence of Reactor. In
practice Reactor is required for the Spring Framework reactive support
and it is expected to be present.
The registry however is now capable of being neutral if Reactor is not
present on the classpath for example where other Spring projects may
not have the same assumptions about Reactor's presence.
Issue: SPR-14902
Collapse ReactiveAdapter hierarchy into a single class that simply
delegates to functions for converting to/from a Publisher.
A private ReactorAdapter extension automaticlaly wraps adapted, "raw"
Publisher's as Flux or Mono depending on the semantics of the target
reactive type.
Issue: SPR-14902
This commit polishes Kotlin nullable support by reusing
MethodParameter#isOptional() instead of adding a new
MethodParameter#isNullable() method, adds
Kotlin tests and introduces Spring Web Reactive
support.
Issue: SPR-14165
Where `isOptional` is used, also check for `isNullable` i.e.
values are not considered required if they are Kotlin nullables:
- spring-messaging: named value method arguments
- spring-web: named value method arguments
- spring-webmvc: request parts
This means that Kotlin client code no longer has to explicity specify
"required=false" for Kotlin nullables -- this information is inferred
automatically by the framework.
Issue: SPR-14165
- ScriptedSubscriber has been renamed to Verifier
- The Publisher is passed to create() instead of verify()
- No more need to specify the generic type explicitly
- Version is now sync with reactor-core
Issue: SPR-14800
Reactor recently added the `ScriptedSubscriber` in its new
`reactor-addons` module. This `Subscriber` revissits the previous
`TestSubscriber` with many improvements, including:
* scripting each expectation
* builder API that guides you until the final verification step
* virtual time support
This commit refactor all existing tests to use this new
infrastructure and removed the `TestSubscriber` implementation.
Issue: SPR-14800
This commit removes the usage of Reactor adapters (about to
be moved from Reactor Core to a new Reactor Adapter module).
Instead, RxReactiveStreams is now used for adapting RxJava
1 and Flowable methods are used for RxJava 2.
Issue: SPR-14824
This commit adds the necessary infrastructure for the support of HTTP
Range requests. The new `ResourceRegionEncoder` can write
`ResourceRegion` objects as streams of bytes.
The `ResourceRegionEncoder` relies on an encoding hint
`BOUNDARY_STRING_HINT`. If present, the encoder infers that multiple
`ResourceRegion`s should be encoded and that the provided boundary
String should be used to separate ranges by mime boundaries.
If that hint is absent, only a single resource region is encoded.
Issue: SPR-14664
Added readableChannel() to Resource, which returns a
java.nio.ReadableByteChannel. The default implementation uses
Channels.newChannel() to create a channel based on what is returned from
getInputStream(). Subclasses have more effecient, file-based
implementations.
Issue: SPR-14698
Fixed bug where the returned Flux from DataBufferUtils.read() would be
completed prematurely if the channel was not ready to read, but did
not reach the end of the file either.
This commit documents the regexp support in `AntPathMatcher` when
matching for URL patterns. This support is also mentioned in places
where developers can register patterns for ViewControllers or resource
handlers.
Issue: SPR-14652
This commit adds a "spring-context-indexer" module that can be added to
any project in order to generate an index of candidate components defined
in the project.
`CandidateComponentsIndexer` is a standard annotation processor that
looks for source files with target annotations (typically `@Component`)
and references them in a `META-INF/spring.components` generated file.
Each entry in the index is the fully qualified name of a candidate
component and the comma-separated list of stereotypes that apply to that
candidate. A typical example of a stereotype is `@Component`. If a
project has a `com.example.FooService` annotated with `@Component` the
following `META-INF/spring.components` file is generated at compile time:
```
com.example.FooService=org.springframework.stereotype.Component
```
A new `@Indexed` annotation can be added on any annotation to instructs
the scanner to include a source file that contains that annotation. For
instance, `@Component` is meta-annotated with `@Indexed` now and adding
`@Indexed` to more annotation types will transparently improve the index
with additional information. This also works for interaces or parent
classes: adding `@Indexed` on a `Repository` base interface means that
the indexed can be queried for its implementation by using the fully
qualified name of the `Repository` interface.
The indexer also adds any class or interface that has a type-level
annotation from the `javax` package. This includes obviously JPA
(`@Entity` and related) but also CDI (`@Named`, `@ManagedBean`) and
servlet annotations (i.e. `@WebFilter`). These are meant to handle
cases where a component needs to identify candidates and use classpath
scanning currently.
If a `package-info.java` file exists, the package is registered using
a "package-info" stereotype.
Such files can later be reused by the `ApplicationContext` to avoid
using component scan. A global `CandidateComponentsIndex` can be easily
loaded from the current classpath using `CandidateComponentsIndexLoader`.
The core framework uses such infrastructure in two areas: to retrieve
the candidate `@Component`s and to build a default `PersistenceUnitInfo`.
Rather than scanning the classpath and using ASM to identify candidates,
the index is used if present.
As long as the include filters refer to an annotation that is directly
annotated with `@Indexed` or an assignable type that is directly
annotated with `@Indexed`, the index can be used since a dedicated entry
wil be present for that type. If any other unsupported include filter is
specified, we fallback on classpath scanning.
In case the index is incomplete or cannot be used, The
`spring.index.ignore` system property can be set to `true` or,
alternatively, in a "spring.properties" at the root of the classpath.
Issue: SPR-11890