This commit introduces a notion of different styles for the formatting
of Duration.
The `@DurationFormat` annotation is added to ease selection of a style,
which are represented as DurationFormat.Style enum, as well as a
supported time unit represented as DurationFormat.Unit enum.
DurationFormatter has been retroffited to take such a Style,
optionally, at construction. The default is still the JDK style a.k.a.
ISO-8601.
This introduces the new SIMPLE style which uses a single number + a
short human-readable suffix. For instance "-3ms" or "2h".
This has the same semantics as the DurationStyle in Spring Boot and
is intended as a replacement for that feature, providing access to the
feature to projects that only depend on Spring Framework.
Finally, the `@Scheduled` annotation is improved by adding detection
of the style and parsing for the String versions of initial delay, fixed
delay and fixed rate.
See gh-22013
See gh-22474
Closes gh-30396
This commit extract spring-related links and recurring external links
into asciidoctor attributes to be used by the Antora toolchain.
It notably homogenizes links to:
- IETF RFCs
- Java Community Process JSRs
- the Java API Documentation (on the Java 17 version)
- Kotlin documentations (on the Kotlinlang.org version)
- the Spring Boot reference guide (on the `html` version)
This commit also reworks most link attributes to follow a
Project-Category-Misc syntax. For example, `spring-boot-docs` rather
than `docs-spring-boot`.
Finally, it makes an effort to clean up remainders from the previous
documentation toolchain, namely the `docs/asciidoc` folder and
`modules/ROOT/pages/attributes.adoc` file.
Closes gh-26864
Closes gh-31619
This commit adds a link in the package-overview pages of KDoc and
Javadoc, pointing to the other documentation's own page.
In order for local tests to work, the build has been slightly modified
to align with the directory structure in the distributed documentation
zip (and consequently with that of the deployed documentation website).
Lastly, the javadoc build was fixed to include the `overview.html` again
in the resulting HTML index, since this is where the KDoc link is added.
See gh-28055
Closes gh-31587
This commit clarifies that the annotation is used to capture events that
are fired from the test `Thread` or descendant threads, since the test
framework uses `InheritableThreadLocal` to store captured events now.
See gh-31079
See gh-30020
This commit adds support for `@Scheduled` annotation on reactive
methods and Kotlin suspending functions.
Reactive methods are methods that return a `Publisher` or a subclass
of `Publisher`. The `ReactiveAdapterRegistry` is used to support many
implementations, such as `Flux`, `Mono`, `Flow`, `Single`, etc.
Methods should not take any argument and published values will be
ignored, as they are already with synchronous support.
This is implemented in `ScheduledAnnotationReactiveSupport`, which
"converts" Publishers to `Runnable`. This strategy keeps track of
active Subscriptions in the `ScheduledAnnotationBeanPostProcessor`,
in order to cancel them all in case of shutdown.
The existing scheduling support for tasks is reused, aligning the
triggering behavior with the existing support: cron, fixedDelay and
fixedRate are all supported strategies.
If the `Publisher` errors, the exception is logged at warn level and
otherwise ignored. As a result new `Runnable` instances will be
created for each execution and scheduling will continue.
The only difference with synchronous support is that error signals
will not be thrown by those `Runnable` tasks and will not be made
available to the `org.springframework.util.ErrorHandler` contract.
This is due to the asynchronous and lazy nature of Publishers.
Closes gh-23533
Closes gh-28515
This commit polishes the previous change, ensuring that if the request
uses a wildcard subtype with an ndjson suffix then the wildcard isn't
present in the response's Content-Type.
Insteand, in that case we would fall back to `applicatin/x-ndjson` (the
base ndjson media type), assuming that the requester is only interested
in the ndjson nature of the underlying representation and not in the
specific semantics of any subtype.
See commit 9332b3f
See gh-26817
This commit ports and adapts spring-jdbc's `BeanPropertyRowMapper` and
`DataClassRowMapper` to spring-r2dbc, allowing to `map` rows or
outParameters to object instances, data classes or records.
See gh-26021
Closes gh-30530
This commit adds `application/*+x-ndjson`, a wildcard media type which
covers all types that can be parsed as nd-json, to the list of media
types the ReactiveTypeHandler considers for a streaming response in
WebMVC.
As a result, a request which for example `Accept` the
`application/vnd.myapp.v1+x-ndjson` media type will generate a response
with the same `Content-Type`, with newline-delimited json objects being
streamed in the response body.
Closes gh-26817
This commit removes the JBoss Application Server external javadoc link,
which covers too many packages and can thus problematically take
precedence for said packages and lead to dead links.
It is replaced by Hibernate javadocs for `org.hibernate.*` packages,
JakartaEE and jsr305 for annotations. We lose a limited number of links
around org.xnio classes and Hibernate-and-JTA-related classes, as a
trade-off.
See gh-30455
See gh-30428
This commit improves how the build deals with javadoc invalid references
in two ways.
Link/see references that are temporarily invalid during javadoc
generation of individual modules are better masked by using the option
`Xdoclint:syntax` instead of `Xdoclint:none` (warnings were still
visible in some cases, e.g. when individually building the javadoc for
a specific module).
Global javadoc-building task `api` now combines `syntax` and `reference`
`Xdoclint` groups, allowing to raise truly invalid references even when
all the modules have been aggregated.
This commit also fixes the 20+ errors which appeared following the later
change in doclet configuration.
Closes gh-30428
This commit fixes the check by avoiding a fallback to eventType's
hasUnresolvableGenerics(). This could previously lead to checking a
generic event type `A<T>` against a listener which accepts unrelated
`B` and return `true` despite the inconsistency.
Note that this wouldn't necessarily surface to the user because there is
a `catch (ClassCastException e)` down the line, which was primarily put
in place to deal with lambda-based listeners but happens to catch an
exception thrown due to the bad result of `supportsEventType`.
The `supportsEventType` now matches generic `PayloadApplicationEvent`
types with a raw counterpart, using the above fallback only in that case
and otherwise ultimately returning `false`.
Closes gh-30399
This commit modifies the way the `@RecordApplicationEvents` annotation
works in tests, allowing for capture of events from threads other than
the main test thread (async events) and for the assertion of captured
event from a separate thread (e.g. when using `Awaitility`).
This is done by switching the `ApplicationEventsHolder` to use an
`InheritedThreadLocal`.
There is a mutual exclusion between support of asynchronous events vs
support of JUnit5 parallel tests with the `@TestInstance(PER_CLASS)`
mode. As a result, we favor the former and now `SpringExtension` will
invalidate a test class that is annotated (or meta-annotated, or
enclosed-annotated) with `@RecordApplicationEvents` AND
`@TestInstance(PER_CLASS)` AND `@Execution(CONCURRENT)`.
See gh-29827
Closes gh-30020
This commit adds support for MethodHandles in SpEL, using the same
syntax as user-defined functions (which also covers reflective Methods).
The most benefit is expected with handles that capture a static method
with no arguments, or with fully bound handles (where all the arguments
have been bound, including a target instance as first bound argument
if necessary). Partially bound MethodHandle should also be supported.
A best effort approach is taken to detect varargs as there is no API
support to determine if an argument is a vararg or an explicit array,
unlike with Method. Argument conversions are also applied. Finally,
array repacking is not always necessary with varargs so it is only
performed when the vararg is the sole argument to the invoked method.
See gh-27099
Closes gh-30045
This commit improves both the javadoc and the reference guide section on
the Elvis SpEL operator to clarify that in addition to `null` objects,
empty Strings also lead the operator to evaluate to its second operand.
The reference guide's advanced snippet is modified to use such an empty
String instead of `null` to make that behavior prominent with some code.
See gh-30318
Closes gh-30352
This commit enables sub-classes to better customize resource selection
and resource loading in `ReloadableResourceBundleMessageSource`, without
a need to duplicate the caching logic of `refreshProperties`.
See gh-30334
Closes gh-30369
On windows, the `*` character is not allowed in a directory's name.
When trying to append a glob pattern to a `Path` (`path.resolve("**")`),
if the underlying `Path.getFileSystem()` is windows then an
`InvalidPathException` is thrown.
The NoHttp plugin doesn't really need a `Path` but a glob `String`, so
this commit uses a simple String concatenation in order to append the
wildcard part (with the canonical path separator for good measure).
Closes gh-30355
This commit adds a note to an exception in `ConstructorResolver`'s
`autowireConstructor` method hinting that attention should be paid to
cases that mix indexed arguments and named arguments. This is especially
when inheriting bean definitions in xml.
Closes gh-29976
Close gh-PR
This commit adds assertions to MockMvc's CookieresultMatchers:
- `attribute` for arbitrary attributes
- `sameSite` for the SameSite well-known attribute
Note that the `sameSite` methods delegate to their `attribute`
counterparts. Note also that Jakarta's `Cookie#getAttribute` method is
case-insensitive, which is reflected in the documentation of the
`attribute` assertion method and the tests.
Closes gh-30285
This commit adds mapping for two types from the `java.time` package,
complementing the types that are already translatable to Sql types
TIME, DATE and TIMESTAMP:
- `OffsetTime` maps to a `TIME_WITH_TIMEZONE`
- `OffsetDateTime` maps to a `TIMESTAMP_WITH_TIMEZONE`
This is in accordance with the B.4 table provided in the JDBC 4.2
specification.
When preparing statements, these `java.time` types use the `setObject`
method. Tests covering the 5 `java.time` classes have also been added.
See gh-28778
See gh-28527
Closes gh-30123
This commit changes the name of two recently introduced methods in the
`MockRestRequestMatchers` class for header and queryParam. These have
been found to cause false negatives in user tests, due to the new
overload taking precedence in some cases.
Namely, using a `Matcher` factory method which can apply to both `List`
and `String` will cause the compiler to select the newest list overload,
by instantiating a `Matcher<Object>`.
This can cause false negatives in user tests, failing tests that used
to pass because the Matcher previously applied to the first String in
the header or queryParam value list. For instance, `equalsTo("a")`.
The new overloads are recent enough and this has enough potential to
cause an arbitrary number of user tests to fail that we break the API
to eliminate the ambiguity, by renaming the methods with a `*List`
suffix.
Closes gh-30220
Closes gh-30238
See gh-29953
See gh-28660
This change fixes a situation where error handling was skipped during
`processCommit()` in case the `doCommit()` failed. The error handling
was set up via an `onErrorResume` operator that was nested inside a
`then(...)`, applied to an inner `Mono.empty()`. As a consequence,
it would never receive an error signal (effectively decoupling the
onErrorResume from the main chain).
This change simply moves the error handling back one level up. It also
simplifies the `doCommit` code a bit by getting rid of the steps that
artificially introduce a `Mono<Object>` return type, which is not really
needed.
A pre-existing test was missing the fact that the rollback didn't occur,
which is now fixed. Another dedicated test is introduced building upon
the `ReactiveTestTransactionManager` class.
Closes gh-30096
This commit adds a `header` variant and a `queryParam` variant to the
`MockRestRequestMatchers` API which take a single `Matcher` over the
list of values.
Contrary to the vararg variants, the whole list is evaluated and the
caller can choose the desired semantics using readily-available iterable
matchers like `everyItem`, `hasItems`, `hasSize`, `contains` or
`containsInAnyOrder`...
The fact that the previous variants don't strictly check the size of the
actual list == the number of provided matchers or expected values is
now documented in their respective javadocs.
See gh-28660
Closes gh-29953
This commit modifies the `DefaultDatabaseClient` implementation in order
to ensure lazier usage of the `Supplier<String>` passed to the sql
method (`DatabaseClient#sql(Supplier)`).
Since technically `DatabaseClient` is an interface that could have 3rd
party implementations, the lazyness expectation is only hinted at in the
`DatabaseClient#sql` javadoc.
Possible caveat: some log statements attempt to reflect the now lazily
resolved SQL string. Similarly, some exceptions can capture the SQL that
caused the issue if known. We expect that these always occur after the
execution of the statement has been attempted (see `ResultFunction`).
At this point the SQL string will be accessible and logs and exceptions
should reflect it as before. Keep an eye out for such strings turning
into `null` after this change, which would indicate the opposite.
Closes gh-29367
This commit takes rfc8297 into account and introduces a newer code 103
HttpStatus value which uses `Early Hints` as the more correct reason
phrase, deprecating the outdated `CHECKPOINT` enum value for 103.
Additionally:
- `HttpStatus.valueOf(103)` will return the new enum value
- `HttpStatusCode#isSameCodeAs(HttpStatusCode)` is introduced to ease
comparison of deprecated enums vs their newer counterparts (or any
instance of a more generic `HttpStatusCode`) by comparing the integer
`value()`
- `HttpStatusTests` covers the new deprecation as well as the three
previously deprecated codes, including a check with the above new
method to ensure they have comparable integer values
Supersedes and Closes gh-27960
As the DSL internally calls `ResultActions.andExpect`, this is done with
a trick where a synthetic `ResultActions` is provided at top level which
stores each `ResultMatcher` in a mutable list.
Once the DSL usage is done, the top level DSL `andExpectAll` turns that
list into a `vararg` passed down to the actual `actions.andExpectAll`.
Closes gh-27317
The block title style previously used was not rendered in HTML and the
title couldn't be differentiated from the text. Though, it was in the
PDF, as italics.
Introducing delimited blocks in the open (`--`) style did introduce
styling, but the vertical alignment isn't great.
This commit turns these block titles to actual (deep) section titles.
In the final HTML, at this depth there is no numbering but bold styling
is there. The PDF rendering has also been verified to have relevant
style.
Closes gh-29694
The link was previously named "Compared to WebFlux", which is easy to
mix up with the various links to equivalent sections in the WebFlux
chapter. Here the links point to a small section comparing the Servlet
Async API to the WebFlux stack from a high perspective.
In this commit we eliminate most of these links, except at the
beginning of the Asynchronous section. We also add a small mention of
the Servlet configuration in the comparison paragraphs, since the
Configuring section is the one furthest from the comparison paragraphs
that used to have a link to it.
Closes gh-29694
This commit extracts the DTD/XSD remote lookup fallback from the
resolveEntity() method into a protected method.
A WARN-level logging statement is added to the extracted fallback in
order to make it clear that remote lookup happened.
Overriding the protected method would allow users to avoid this
fallback entirely if it isn't desirable, without the need to duplicate
the local resolution code.
Closes gh-29697