This commit makes sure that the DefaultPartHttpMessageReader uses a
random temporary directory to store uploaded files, so that two
instances do not collide.
See gh-26931
This commit makes sure that Synchronoss uses a random temporary
directory to store uploaded files, so that two instances do not collide.
Closes gh-26931
Recent commit dddcc5e9ad ensured a
trailing "/" in the Origin header has no effect. This commit does the
same for a trailing "/" in configured patterns.
See gh-26892
The pattern was changed in 65797d04f2
to check for characters up until "/", instead of for digits, but now
also checks up until "?" and "#".
Closes gh-26905
Prior to this commit, when Web MVC attempted to resolve a constructor
argument for a data class constructor with @ModelAttribute binding,
ModelAttributeMethodProcessor failed to unwrap the array returned by
WebRequest.getParameter(String).
According to the Javadoc for WebRequest.getParameter(String), "a
single-value parameter will be exposed as an array with a single
element."
This commit fixes this issue by extracting the single value from such
an array and using that as the constructor argument (potentially
converted by the WebDataBinder).
Closes gh-25200
This commit revises the fix submitted in 959e6d1745 by ensuring that
empty file input is converted to a MockPart with the supplied name, an
empty filename, "application/octet-stream" as the content type, and
empty content.
This aligns with the behavior of Servlet containers, as tested with the
interaction between Firefox and a standard Servlet running in a Jetty
Servlet container.
Closes gh-26799
Prior to this commit, when using HtmlUnit with empty file input,
MockMvc's HtmlUnitRequestBuilder would throw a NullPointerException
when attempting to create a MockPart based on the null File.
This commit ensures that empty file input is converted to a MockPart
with a valid name but with a null filename, a null content type, and
empty content.
Closes gh-26799
Prior to this commit, we registered custom values in the build scan for
the main and test toolchains based on input values provided via the
mainToolchain and testToolchain project properties.
Beginning with this commit, the custom values we register are based on
the available metadata for the resolved JDK/JVM for each toolchain.
For example, instead of registering the following custom value...
Test toolchain : JDK11
... we now register the following which includes the vendor, version,
and installation path of the JDK/JVM.
Test toolchain : AdoptOpenJDK 11 (/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home)
Once Gradle's JavaInstallationMetadata includes the exact version, we
will likely use that instead of the installation path.
See gh-25787
Prior to this commit, the task parameters for the CI project checks were
overridden by a task anchor. This commit splits the anchor declaration
and ensures that the `TEST_TOOLCHAIN` setting is set for the JDK
variant builds.
See gh-25787
Commit 3eec27a723 introduced a custom resource filter for projects
imported into Eclipse IDE. However, commit 85eb589c2e introduced
generated source files within the Gradle 'build' folder, and the filter
prevents Eclipse from seeing the generated sources, resulting in build
errors within the spring-oxm project in Eclipse.
This commit therefore effectively reverts 3eec27a723 by removing the
resource filter.
See gh-25787
Prior to this commit, @ModelAttribute(binding=false) was honored with
Spring Web MVC but not with WebFlux.
This commit adds support for disabling binding via @ModelAttribute with
WebFlux by adding a check to resolveArgument(...) in
ModelAttributeMethodArgumentResolver.
Closes gh-26856
This commit fixes various issues with the configuration of the Gradle
Java toolchain in the build.
First, the configuration of build properties is fixed in the CI pipeline
because it wasn't properly checked.
The JMH plugin is also upgraded and we now configure its toolchain
support.
This commit also rewrites the XJC tasks in the spring-oxm module,
leveraging a Gradle plugin that creates actual compile tasks we can
configure.
See gh-25787
This commit makes sure that LinkedCaseInsensitiveMap::computeIfAbsent
honors the contract of the method, and also replaces the old entry if
that mapped to null.
Closes gh-26868
This commit makes sure that LinkedCaseInsensitiveMap::putIfAbsent honors
the contract of the method, and also replaces the old entry if that
mapped to null.
Closes gh-26868
This commit fixes a potential memory leak, since PropertyComparator
previously kept an indirect reference to the value it last compared.
Closes gh-26869
This commit makes sure that any error handlers registered on the route
are also applied when an error occurs asynchronously. This commit
applies to asynchronous bodies with both CompletableFuture and Reactive
Streams, as well as completely asynchronous responses.
Closes gh-26831
Prior to this commit, MySQLMaxValueIncrementer could not be used when
the MySQL database was configured to use safe-updates mode.
See https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates
This commit introduces a `limit 1` clause to the generated update
statement to allow MySQLMaxValueIncrementer to be compatible with
MySQL safe-updates mode.
Closes gh-26858
Before this commit, HttpStatus::resolve used the values() method in its
logic. This causes a new array to be allocated for each invocation,
and results in memory overhead.
This commit makes a copy of the HttpStatus values array, and uses that
to resolve status codes.
Closes gh-26842
Prior to this commit, evaluating validation hints for
@javax.validation.Valid caused exceptions being raised when getting the
value of this annotation, which does not exist. Bypassing
AnnotationUtils.getValue() in those cases can improve performance by
avoiding the cost incurred by raising exceptions.
See gh-26787
Prior to this commit, two tests for exception handling regarding
@DateTimeFormat processing only passed on Java 8. This is due to the
fact that the toString() implementation for annotations changed in Java
9. Specifically, the representation for arrays changed from [] to {},
and strings are enclosed in double quotes beginning with Java 9.
This commit ensures that the affected @DateTimeFormat tests pass on
Java 9+, by making the assertions more lenient regarding toString()
output for annotations.
See gh-26777
See gh-26804
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.
gh-26777 addressed that regression for `java.time` support; whereas,
this commit addresses that regression for legacy Date types.
This commit ensures that the original ParseException is set as the
cause for any newly created ParseException, thereby retaining the
original exception as the root cause.
Closes gh-26804
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.
This commit ensures that the original DateTimeParseException is set as
the cause for any newly created DateTimeParseException, thereby
retaining the original exception as the root cause.
Closes gh-26777
Some operating systems delete temp files not just when booting up, but
also during operation. This commit makes sure that the
DefaultPartHttpMessageReader recreates the directory used to store
files in, if it's not there.
Closes gh-26790
This commit allows the spring-expression module to be more easily repackaged
for embedding in third-party JARs -- for example, via the Shadow Gradle plugin.
Closes gh-26779
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header, which is sent when the client sends unsupported
data in PATCH requests.
See section 2.2 of RFC 5789.
Closes gh-26759
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header in OPTIONS requests, as defined in section 3.1 of
RFC 5789.
See gh-26759
This commit adds support for Kotlin non-nullable type which resolves
to primitive Java types in BridgeMethodResolver#findBridgedMethod.
Closes gh-26585
Prior to this commit, if a test class annotated with @DirtiesContext
and @EnabledIf/@DisabledIf with `loadContext = true` was disabled due
to the evaluated SpEL expression, the ApplicationContext would not be
marked as dirty and closed.
The reason is that @EnabledIf/@DisabledIf are implemented via JUnit
Jupiter's ExecutionCondition extension API which results in the entire
test class (as well as any associated extension callbacks) being
skipped if the condition evaluates to `disabled`. This effectively
prevents any of Spring's TestExecutionListener APIs from being invoked.
Consequently, the DirtiesContextTestExecutionListener does not get a
chance to honor the class-level @DirtiesContext declaration.
This commit fixes this by implementing part of the logic of
DirtiesContextTestExecutionListener in
AbstractExpressionEvaluatingCondition (i.e., the base class for
@EnabledIf/@DisabledIf support). Specifically, if the test class for an
eagerly loaded ApplicationContext is disabled,
AbstractExpressionEvaluatingCondition will now mark the test
ApplicationContext as dirty if the test class is annotated with
@DirtiesContext.
Closes gh-26694
This commit fixes the missing pieces in our Maven Central publication
pipeline. Our first attempt at releasing with it showed a few problems:
* the promote task did not have the artifacts downladed with the
artifactory repository
* we applied the wrong Sonatype credentials to the task
* the github changelog task would fail because of docker rate limiting
since we were not using the right type of resource, which is
configured with the proper caching mechanism
See gh-26654
Prior to this commit, the Spring Framework build would rely on
setting a custom Java HOME for building all sources and tests
with that JDK.
This approach is not flexible enough, since we would be testing
the source compatibility against a recent JDK, but not a common
case experienced by the community: compiling and running
application code with a recent JDK and the official, JDK8-based
Framework artifacts.
This method is also limiting our choice of JDKs to the ones
currently supported by Gradle itself.
This commit introduces the support of Gradle JVM Toolchains in
the Spring Framework build.
We can now select a specific JDK for compiling the main
SourceSets (Java, Groovy and Kotlin) and another one for
compiling and running the test SourceSets:
`./gradlew check -PmainToolChain=8 -PtestToolchain=15`
Gradle will automatically find the JDKs present on the host or
download one automcatically. You can find out about the ones
installed on your host using:
`./gradlew -q javaToolchains`
Finally, this commit also refactors the CI infrastructure to:
* only have a single CI image (with all the supported JDKs)
* use this new feature to compile with JDK8 but test it
against JDK11 and JDK15.
Closes gh-25787
We now support Oracle's bind marker scheme that identifies dynamic
parameters using names that are prefixed with a colon such as
`:P0_myparam`.
Closes gh-26680
Prior to this commit, @DateTimeFormat only supported a single format
for parsing date time values via the style, iso, and pattern attributes.
This commit introduces a new fallbackPatterns attribute that can be
used to configure multiple fallback patterns for parsing date time
values. This allows applications to accept multiple input formats for
date time values.
For example, if you wish to use the ISO date format for parsing and
printing but allow for lenient parsing of user input for various
additional date formats, you could annotate a field or method parameter
with configuration similar to the following.
@DateTimeFormat(
iso = ISO.DATE,
fallbackPatterns = { "M/d/yy", "dd.MM.yyyy" }
)
Closes gh-20292
This commit skips the Bintray-related tasks in our CI pipeline and
instead relies on Maven Central for publishing Spring Framework
artifacts.
This commit also updates the CI pipeline to sign the artifacts directly
with the `artifactory-resource`.
Closes gh-26654
Previously we registered 3 AsyncListener's from the request, from the
response, and from the Servlet adapter.
After this change, only the Servlet adapter registers a listener and
the others are delegated to. This consolidates the handling of
AsyncListener events so that it's easier to discover, trace, and
enforce the order of handling.
See gh-26434
Prior to this commit, a method-level @CrossOrigin maxAge value did not
override a class-level @CrossOrigin maxAge value. This contradicts the
Javadoc for @CrossOrgin which states the following.
For those attributes where only a single value can be accepted such
as allowCredentials and maxAge, the local overrides the global
value.
This commit ensures that a method-level @CrossOrigin maxAge value
overrides a class-level @CrossOrigin maxAge value.
Closes gh-26619
Prior to this commit, `ServerHttpRequest.mutate()` would not reflect
changes made on the "Accept" and "Content-Type" HTTP headers.
This was due to the fact that the instantiation of a new request based
on the mutated values would not use the writable HTTP headers used
during the mutation, but rather a read-only view of the headers backed
by `ReadOnlyHttpHeaders`.
`ReadOnlyHttpHeaders` caches those values for performance reasons, so
getting those from the new request would not reflect the changes made
during the mutation phase.
This commit ensures that the new request uses the mutated headers.
Fixes gh-26615
This commit ensures handling is cancelled in case of onError/Timeout
callback from the Servlet container.
Separately we detect the same in ServletServerHttpRequest and
ServletServerHttpResponse, which signal onError to the read publisher
and cancel writing, but if the onError/Timeout arrives after reading
is done and before writing has started (e.g. longer handling), then
neither will reach handling.
See gh-26434, gh-26407
For setAsText, if the text argument is a file: URL for a path that does not exist, Paths.get(text) is called where text is a file: URL, which doesn't work - the result is an InvalidPathException.
To fix this issue, also check that the resource isn't a file before calling Paths.get(). That way, resources that are files skip to the other branch.
Class.getResource, ClassLoader.getResource, and ClassLoader.getSystemResource will throw IllegalArgumentException if a malformed URL is provided to them.
According to its javadoc, resolveURL should return null if not resolvable, so catch the IllegalArgumentException and return null.
Prior to this commit, the implementation of processKeyedProperty() in
AbstractNestablePropertyAccessor resulted in a
`java.lang.IllegalArgumentException: array element type mismatch` when
the property expression had more than one property key and the last key
should cause the array to grow automatically.
For example, given a property `int[][] multiArray` and property
expression `multiArray[1][3]`, the `processKeyedProperty()` method
created a new array object and assigned it to `multiArray`; whereas,
the new array object should have be assigned to `multiArray[1]`.
This commit fixes this issue.
Closes gh-26600
In order to reduce the focus on the deprecated @Required support, this
commit removes the RequiredAnnotationBeanPostProcessor section and
replaces it with a TIP and an updated NOTE.
See gh-26578
Since Spring Framework 5.2, the LoadTimeWeaver no longer weaves bean
classes annotated with @Component. This is a regression caused by the
changes in 40c62139ae, stemming from the fact that any class annotated
or meta-annotated with @Component is considered to be a candidate
configuration class in 'configuration lite' mode (i.e., a class without
the @Configuration annotation and without any @Bean methods) and
therefore now has its class eagerly loaded. This results in the class
being loaded before the LoadTimeWeaver has a chance to weave it.
This commit fixes this regression by explicitly avoiding eager class
loading for any 'lite' @Configuration or @Component class without @Bean
methods.
Closes gh-26199
Prior to this commit, `ResourceUrlProvider` would listen and consider
all `ContextRefreshedEvent` and use the given context to detect
`SimpleUrlHandlerMapping`.
This could lead to situations where a `ResourceUrlProvider` uses another
application context than its own (in a parent/child context setup) and
detect the wrong set of handlers.
Because `ResourceUrlProvider` locks itself once the auto-detection is
done, we need to ensure that it considers only events sent by its
application context.
Fixes gh-26561
Prior to this commit, MockHttpServletResponse only included the Expires
attribute in the generated Cookie header if the Max-Age attribute had
also been set.
This commit supports including the Expires attribute in the generated
Cookie Header even when the Max-Age attribute has not been set.
Closes gh-26558
Add factory methods to `AbstractEnvironment` that allow a custom
`ConfigurablePropertyResolver` and `MutablePropertySources` instance
to be used.
See gh-26462
With the introduction of the -H:+InlineBeforeAnalysis native image
compiler flag in GraalVM 21.0.0, it is now possible to use an utility method and get code
removal at build time.
This flag will be enabled as of Spring Native 0.9.0.
closes gh-25795
This commit updates the reference manual to point out that one may use
`.` instead of `$` as the nested class separator when providing a fully
qualified class name for a nested class in XML configuration.
This commit also updates the test for ClassUtils#forName to assert
support for `.` instead of `$`.
Closes gh-26540
gh-24281 introduced support to honor generic type information in
BeanUtils.copyProperties(), but that introduced a regression.
Specifically, if the supplied source or target object lacked generic
type information for the return type of the read-method or the
parameter type of the write-method for a given property, respectively,
the two properties would be considered a mismatch and ignored. This can
occur if the source or target object is a java.lang.reflect.Proxy since
the dynamically generated class for the proxy loses the generic type
information from interfaces that the proxy implements.
This commit fixes this regression by ignoring generic type information
if either the source or target property is lacking generic type
information.
Closes gh-26531
This commit better aligns how URI variable placeholders are detected
in UriComponentsBuilder#encode (i.e. the pre-encoding of the literal
parts of a URI template) and how they are expanded later on.
The latter relies on a pattern that stops at the first closing '}'
which excludes the possibility for well-formed, nested placeholders
other than variables with regex syntax, e.g. "{year:\d{1,4}}".
UriComponentsBuilder#encode now also stops at the first closing '}' and
further ensures the placeholder is not empty and that it has '{' before
deciding to treat it as a URI variable.
Closes gh-26466
This commit changes the condition in the if-block to check the number of
available processors instead of currently active threads with the hope
that doing so will prove more reliable on the CI server.
`spring-beans` ships a `YamlProcessor` that's used as a base class by
`YamlMapFactoryBean` and `YamlPropertiesFactoryBean`. These
implementations have a clear use case: mapping application-internal Yaml
documents for configuration or infrastructure purposes.
Since this use case rarely requires extended types support from the
underlying library, and since we're offering ways to list custom types
(since #25152), we'll restrict to java standard types only by default.
This simplifies the setup and focuses the abstract class on the core
use cases.
Closes gh-26530
This commit makes sure the StringDecoder supports stripping off
multi-line delimiters, such as \r\n. Specifically, we ensure that the
delimiter is stripped from the joined buffer.
Closes gh-26511
When a broker message handler is not configured with any prefixes, it will
process all messages by default, but user destination messages should be
pre-processed by the userDestinationMessageHandler first. This change
protects against that.
Closes gh-26474
This commit aligns the documentation in the reference manual with the
actual source code for StoredProcedure with regard to public execute()
methods.
Closes gh-26505
Previously this method returned headers only when a Content-Type part header
was present. Now it is guaranteed to return headers (possibly empty) as long
as there is a MultipartFile or Part with the given name.
Closes gh-26501
Prior to this commit, if an SQLException was thrown while retrieving
column metadata from the database, SimpleJdbcInsert would generate an
INSERT statement that was syntactically valid but missing columns,
which could lead to data silently missing in the database (for nullable
columns).
This commit fixes this by clearing all collected column metadata if an
SQLException is thrown while processing the metadata. The result is
that an InvalidDataAccessApiUsageException will be thrown later while
generating the INSERT statement. The exception message now contains an
additional hint to make use of SimpleJdbcInsert#usingColumns() in order
to ensure that all required columns are included in the generated
INSERT statement.
SimpleJdbcCall can also encounter an SQLException while retrieving
column metadata for a stored procedure/function, but an exception is
not thrown since a later invocation of the stored procedure/function
will likely fail anyway due to missing arguments. Consequently, this
commit only improves the warning level log message by including a hint
to make use of SimpleJdbcCall#addDeclaredParameter().
Closes gh-26486
Prior to this commit, calls to setLocale() MockHttpServletResponse
would result in a NullPointerException if the supplied Locale was null.
Although the Javadoc for setLocale(Locale) and addHeader(String, String)
in javax.servlet.ServletResponse does not specify how a null
Locale should be handled, both Tomcat and Jetty simply ignore a null
value.
This commit therefore updates MockHttpServletResponse to silently
ignore a null Locale passed to setLocale().
Closes gh-26493
Prior to this commit, calls to setHeader() and addHeader() in
MockHttpServletResponse would result in an IllegalArgumentException or
NullPointerException if the supplied header value was null.
Although the Javadoc for setHeader(String, String) and
addHeader(String, String) in javax.servlet.http.HttpServletResponse
does not specify how a null header value should be handled, both Tomcat
and Jetty simply ignore a null value. Furthermore,
org.springframework.http.HttpHeaders.add(String, String) declares the
headerValue parameter as @Nullable.
This commit therefore updates MockHttpServletResponse to silently
ignore null header values passed to setHeader() and addHeader().
Closes gh-26488
1. Update the HandlerMapping contract to state that CORS checks are expected
to be applied before returning a handler.
2. DispatcherHandler checks explicitly for pre-flight requests or CORS failed
requests and skips handling for both. Technically no change since
AbstractHandlerMapping already returns a NO_OP_HANDLER for those cases.
The purpose however is for the DispatcherHandler to also guarantee more
explicitly that no such handling can take place for such cases.
As one consequence, this makes it possible to invoke the DispatcherHandler from
anywhere in the WebFilter chain in order to "handle" a pre-flight request, and
then skip the rest of the WebFilter chain.
See gh-26257
Prior to this commit, if the DataSource in the
DataSourceFromTransactionManager was wrapped in a proxy implementing
InfrastructureProxy, SqlScriptsTestExecutionListener would throw an
exception stating that the DataSource in the ApplicationContext and the
DataSource in the DataSourceFromTransactionManager were not the same.
This commit unwraps both data sources and compares the underlying
target instances to check for equality.
In addition, this commit makes the unwrapResourceIfNecessary() method in
TransactionSynchronizationUtils public.
Closes gh-26422
This commit introduces warnings in invokeBeanFactoryPostProcessors()
and registerBeanPostProcessors() to deter people from submitting PRs
that result in breaking changes.
Closes gh-26401
Prior to this commit, `SimpleUrlHandlerMapping` and other
implementations of `AbstractUrlHandlerMapping` would not strip the
Servlet context path from the request path before performing path
matching with PathPattern instances.
This resulted in requests not matching as expected if the application
was configured with a Servlet context path.
This commit ensures that the `RequestPath` "path whithin the
application" is used for matching against path patterns.
Fixes gh-26411
This commit makes sure that the CronExpression rolls back the time to
midnight when dealing with Quartz expression fields (such as "L", "LW",
etc.).
Closes gh-26390
Remove support for open polymorphic serialization in
kotlinx.serialization web converters and codecs in order
to prevent serialization handling suitable for Jackson
or other general purpose Java JSON libraries.
This will probably need further refinements for collections
for example, and could ultimately be fixed when
kotlinx.serialization will provide a dedicated function to
evaluate upfront if a type can be serialized or not.
Closes gh-26298
This commit documents ApplicationContext initialization and shutdown
logging semantics for console output triggered in conjunction with the
Spring TestContext Framework.
Closes gh-25385
Prior to this commit, WebFlux native headers adapters would delegate the
`httpHeaders.keySet` to underlying implementations that do not honor the
`remove*` methods.
This commit fixes the `Set` implementation backing the
`httpHeaders.keySet` and ensures that headers can be safely removed from
the set.
Fixes gh-26361
Instead of using a new bounded elastic scheduler per
DefaultPartHttpMessageReader instance, which creates daemon threads that
are not shut down, we now use the shared bounded elastic scheduler.
Closes gh-26347
This commit only writes the 'charset' parameter in the written headers
if it is non-default (not UTF-8), since RFC7578 states that the only
allowed parameter is 'boundary'.
See gh-25885
Closes gh-26290
An empty buffer for RSocket is an empty message and while some codecs
such as StringDecoder may be able turn that into something such as an
empty String, for other formats such as JSON it is invalid input.
Closes gh-26344
Prior to this commit, the `ServletServerHttpResponse` would copy headers
from the `HttpHeaders` map and calls methods related to headers exposed
as properties (content-type, character encoding).
Unlike its reactive variant, this would not set the content length.
Depending on the Servlet container implementation, this could cause
duplicate Content-Length response headers in the actual HTTP response.
This commit aligns both implementations and ensures that the
`setContentLengthLong` method is called if necessary so that the Servlet
container can ensure a single header for that.
Fixes gh-26330
Prior to this commit, the `ResourceHttpRequestHandler` would write the
resource size to the "Content-Length" response header.
This is already done by the underlying `ResourceHttpMessageConverter`
and `ResourceRegionHttpMessageConverter`.
This commit avoid this duplicate operation and delegates instead to the
converters.
See gh-26330
Closes gh-26340
- Remove unused clone() code left-over from previous way of cloning.
- Lazy instantiation of ServerCodecConfigurer in
HttpWebHandlerAdapter since in most cases the configurer instance
is set externally.
Closes gh-26263
This commit reverts some changes done in 2d5f9723fa
in order to fix JdbcOperations.queryForObject and
JdbcOperations.queryForList.
It is not possible to provide a vararg variant in Kotlin
for now due to a signature clash, but that will probably
make sense in Spring Framework 6 timeframe along to array
based variant removal for both Java and Kotlin.
Closes gh-26312
Since support for the commandName attribute was removed from the
implementation of FormTag in Spring Framework 5.0, the presence of the
commandName attribute in the spring-form.tld file is no longer valid
and can lead one to assume that the commandName attribute is still
supported -- for example when using code completion in a JSP editor.
This commit therefore removes the obsolete commandName attribute in
spring-form.tld.
Closes gh-26337
This commit introduces tests that verify support for using
@PropertySource as a repeatable annotation without the
@PropertySources container, both locally on an @Configuration class
and on a custom composed annotation.
See gh-26329
This commit introduces a new feature in the Spring TestContext
Framework (TCF) that provides support for recording application events
published in the ApplicationContext so that assertions can be performed
against those events within tests. All events published during the
execution of a single test are made available via the ApplicationEvents
API which allows one to process the events as a java.util.Stream.
The following example demonstrates usage of this new feature.
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
class OrderServiceTests {
@Autowired
OrderService orderService;
@Autowired
ApplicationEvents events;
@Test
void submitOrder() {
// Invoke method in OrderService that publishes an event
orderService.submitOrder(new Order(/* ... */));
// Verify that an OrderSubmitted event was published
int numEvents = events.stream(OrderSubmitted.class).count();
assertThat(numEvents).isEqualTo(1);
}
}
To enable the feature, a test class must be annotated or meta-annotated
with @RecordApplicationEvents. Behind the scenes, a new
ApplicationEventsTestExecutionListener manages the registration of
ApplicationEvents for the current thread at various points within the
test execution lifecycle and makes the current instance of
ApplicationEvents available to tests via an @Autowired field in the
test class. The latter is made possible by a custom ObjectFactory that
is registered as a "resolvable dependency". Thanks to the magic of
ObjectFactoryDelegatingInvocationHandler in the spring-beans module,
the ApplicationEvents instance injected into test classes is
effectively a scoped-proxy that always accesses the ApplicationEvents
managed for the current test.
The current ApplicationEvents instance is stored in a ThreadLocal
variable which is made available in the ApplicationEventsHolder.
Although this class is public, it is only intended for use within the
TCF or in the implementation of third-party extensions.
ApplicationEventsApplicationListener is responsible for listening to
all application events and recording them in the current
ApplicationEvents instance. A single
ApplicationEventsApplicationListener is registered with the test's
ApplicationContext by the ApplicationEventsTestExecutionListener.
The SpringExtension has also been updated to support parameters of type
ApplicationEvents via the JUnit Jupiter ParameterResolver extension
API. This allows JUnit Jupiter based tests to receive access to the
current ApplicationEvents via test and lifecycle method parameters as
an alternative to @Autowired fields in the test class.
Closes gh-25616
This new option allows a cancel signal to abort the request, which is
how we expect a connection to be aborted in a reactive chain that
involves the WebClient.
Closes gh-26287
This commit introduces computeAttribute() as an interface default method
in the AttributeAccessor API. This serves as a convenience analogous to
the computeIfAbsent() method in java.util.Map.
Closes gh-26281
Prior to this commit, the `NettyHeadersAdapter` would directly delegate
the `add()` and `set()` calls to the adapted
`io.netty.handler.codec.http.HttpHeaders`. This implementation rejects
`null` values with exceptions.
This commit aligns the behavior here with other implementations, by not
rejecting null values but simply ignoring them.
Fixes gh-26274
This commit makes sure that the matching pattern attributes is cleared
when an async result has been obtained, so that the subsequent
dispatch starts from scratch.
Closes gh-26239
This commit refines ConfigurationClassPostProcessor behavior in
native images by skipping configuration classes enhancement
instead of raising an error.
See spring-projects-experimental/spring-graalvm-native#248 for
more details.
Closes gh-26236
HttpMessageWriter implementations now attach the request log prefix
as a hint to created data buffers when the logger associated with
the writer is at DEBUG level.
Closes gh-26230
This commit updates websocket and messaging configurations in order
to not use CGLIB proxies anymore. The goal here is to allow support
in native executables and to increase the consistency across the
portfolio.
Closes gh-26227
The previous implementation uses ArrayList for storing resolved
resources and ArrayList has O(n) time complexity for the contains
operation. By switching to the HashSet for storing resolved
resources we improve the time complexity of this operation to be O(1).
See gh-25927
This commit improves the Javadoc for the `ForwardedHeaderFilter`
(Servlet Filter) and `ForwardedHeaderTransformer` (reactive variant) so
as to mention security considerations linked to Forwarded HTTP headers.
Closes gh-26081
Prior to this commit, the `SimpleApplicationEventMulticaster` would be
instrumented with the `ApplicationStartup` and start/stop events for
invoking event listeners (`spring.event.invoke-listener`).
This feature was already limited to single-threaded event publishers,
but is still flawed since several types of events can happen
concurrently. Due to the single-threaded nature of the startup sequence,
our implementation should not produce startup events concurrently.
This can cause issues like gh-26057, where concurrent events lead to
inconcistencies when tracking parent/child relationships.
This commit removes the `spring.event.invoke-listener` startup event as
a result.
Fixes gh-26057
This commit introduces AsyncServerResponse, an extension of
ServerResponse that is returned from ServerResponse.async and that
allows users to get the future response by calling the block method.
This is particularly useful for testing purposes.
This commit adds support for sending Server-Sent Events in WebMvc.fn,
through the ServerResponse.sse method that takes a SseBuilder DSL.
It also includes reference documentation.
Closes gh-25920
Remove the overriden pathVariable method from the nested request
wrapper,so that the merged attributes are used instead of the ones
provided by servlet.
Closes gh-26163
1. Revert changes in setHeader from 5.2.9 that caused regression on self-copy.
2. Update copyHeaders to ensure it still gets a copy of native headers.
3. Exit if source and target are the same instance, as an optimization.
Closes gh-26155
This commit introduces the following changes:
- Converters/codecs are now used based on generic type info.
- On WebMvc and WebFlux, kotlinx.serialization is enabled along
to Jackson because it only serializes Kotlin @Serializable classes
which is not enough for error or actuator endpoints in Boot as
described on spring-projects/spring-boot#24238.
TODO: leverage Kotlin/kotlinx.serialization#1164 when fixed.
Closes gh-26147
This commit only writes the 'charset' parameter in the written headers
if it is non-default (not UTF-8), since RFC7578 states that the only
allowed parameter is 'boundary'.
Closes gh-25885
Recently the Spring Framework projects could no longer be imported into
Eclipse IDE without compilation errors in JMH sources.
This commit addresses this issue by applying workarounds for bugs in
Gradle and the JMH plugin for Gradle.
Gradle bug: https://github.com/gradle/gradle/issues/14932
JMH plugin bug: https://github.com/melix/jmh-gradle-plugin/issues/157
The Gradle bug has already been fixed in Gradle 6.8 RC1; however, the
issue for the JMH plugin bug seems not to have been triaged yet.
Closes gh-26140
Despite the code duplication, we will not delegate to
AopUtils.invokeJoinpointUsingReflection() from
AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs().
The rationale is that the exception message in
invokeAdviceMethodWithGivenArgs() provides additional context via the
pointcut expression, and we would lose that additional context if we
simply delegate to AopUtils.invokeJoinpointUsingReflection(). We could
introduce an overloaded variant of invokeJoinpointUsingReflection() that
accepts an additional argument to provide the additional context for the
exception message, but we don't think that would be the best solution
for this particular use case.
In light of that, we are simply removing the TODO.
Closes gh-26126
Prior to this change the checks for isVariableName were duplicated
in 2 different locations. The logic has been moved to AspectJProxyUtils
to allow for re-use in those places and so that it benefits from any
optimizations that are done.
There are more locations which could benefit from not using a
toCharArray on a String, but rather use the charAt method from
the String itself. This to prevent an additional copy of the
char[] being created.
Prior to this commit, the promote task in the CI release pipeline would
write the "concourse-release-scripts" CONSOLE logs to /dev/null; this
commit ensures that we can read those while promoting artifacts.
gh-19930 introduced support for finding class-level test configuration
annotations on enclosing classes when using JUnit Jupiter @Nested test
classes, but support for @DynamicPropertySource methods got overlooked
since they are method-level annotations.
This commit addresses this shortcoming by introducing full support for
@NestedTestConfiguration semantics for @DynamicPropertySource methods
on enclosing classes.
Closes gh-26091
Prior to this commit, the test("test") conditions used in
AutowiredConfigurationErrorsIntegrationTests inadvertently asserted
that the invoked test methods reside in an org.springframework.test
subpackage, which is always the case for any test method in the
`spring-test` module. In other words, "test" is always a substring of
"org.springframework.test...", which is not a meaningful assertion.
This commit ensures that the JUnit Platform Test Kit is asserting the
actual names of test methods.
This commit introduces `and()` default methods in the MethodFilter and
FieldFilter functional interfaces in ReflectionUtils in order to simplify
uses cases that need to compose filter logic.
Closes gh-26063
Prior to this commit, a developer may have accidentally annotated a
JUnit Jupiter test method or lifecycle method with @Autowired, and that
would have potentially resulted in an exception that was hard to
understand. This is because the Spring container considers any
@Autowired method to be a "configuration method" when autowiring the
test class instance. Consequently, such an @Autowired method would be
invoked twice: once by Spring while attempting to autowire the test
instance and another time by JUnit Jupiter when invoking the test or
lifecycle method. The autowiring invocation of the method often leads
to an exception, either because Spring cannot satisfy a dependency (such
as JUnit Jupiter's TestInfo) or because the body of the method fails due
to test setup that has not yet been invoked.
This commit introduces validation for @Autowired test and lifecycle
methods in the SpringExtension that will throw an IllegalStateException
if any @Autowired method in a test class is also annotated with any of
the following JUnit Jupiter annotations.
- @Test
- @TestFactory
- @TestTemplate
- @RepeatedTest
- @ParameterizedTest
- @BeforeAll
- @AfterAll
- @BeforeEach
- @AfterEach
Closes gh-25966
The alternative is to use a filter but this makes it a little easier
and also guarantees that it will be downstream from all filters
regardless of their order, and therefore the Context will be visible
to all of them.
Closes gh-25710
In 5.3.x and forward, completely avoid logging unsent CONNECT messages
that are most likely authentication issues before the session is even
established.
Closes gh-26026
Adds a static INSTANCE to FullyQualifiedAnnotationBeanNameGenerator,
just like its parent class, AnnotationBeanNameGenerator, does.
The class doesn't have any state and overriding/hiding the INSTANCE of
the superclass, this prevents unintended use of a regular
AnnotationBeanNameGenerator through
FullyQualifiedAnnotationBeanNameGenerator.INSTANCE.
Prior to this commit, MergedAnnotationCollectors.toAnnotationSet()
created an intermediate ArrayList for storing the results prior to
creating a LinkedHashSet in the finishing step.
Since the creation of the intermediate list is unnecessary, this commit
simplifies the implementation of toAnnotationSet() by using the
Collector.of() factory method that does not accept a `finisher` argument.
The resulting Collector internally uses a `castingIdentity()` function
as the `finisher`.
Closes gh-26031
Prior to this commit, the findAllLocalMergedAnnotations() method in
AnnotationDescriptor altered between the use of TYPE_HIERARCHY and
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES for the SearchStrategy, depending
on @NestedTestConfiguration semantics; however, when searching for
"local" annotations, there is no need to search the enclosing class
hierarchy since AnnotationDescriptor#next() handles that use case.
This commit therefore switches to using only the TYPE_HIERARCHY
strategy.
This commit also discontinues the use of
MergedAnnotationCollectors.toAnnotationSet() in order to avoid the
unnecessary creation of a temporary List when collecting synthesized
annotations in a LinkedHashSet.
Closes gh-25985
This commit configures the logging level to DEBUG for the concourse
release scripts tasks.
This is useful to get a clue on where those long-running tasks are at.
With this commit, bean definition profiles declared via @ActiveProfiles
are once again stored in registration order, in order to support use
cases in Spring Boot and other frameworks that depend on the
registration order.
This effectively reverts the changes made in conjunction with gh-25973.
Closes gh-26004
This commit makes copies of the default headers and cookies when a
WebClient is built, so that subsequent changes to these do not affect
previously built clients.
Closes: gh-25992
Allow the body to be written in order for all headers to be set
as they would be on HTTP GET. The body content is ignored as a
lower level.
See gh-25976
Previous incarnation of MockMvc Kotlin DSL tried to reuse directly
Java APIs like ModelResultMatchers or StatusResultMatchers, but
when using multiple matchers in DSL blocks like model { } or
status { }, only the last statement was taken in account which
was very confusing.
This refactoring provides dedicated Kotlin DSLs for matchers.
The main API breaking changes is that functions like isOk() need to be
invoked with the parenthesis, isOk is not supported anymore (on purpose).
Closes gh-24103
Prior to this commit, if a developer accidentally copied and pasted the
same @ContextConfiguration or @TestPropertySource declaration from a
test class to one of its subclasses or nested test classes, the Spring
TestContext Framework (TCF) would merge the inherited configuration
with the local configuration, resulting in different sets of
configuration metadata which in turn resulted in a different
ApplicationContext instance being loaded for the test classes. This
behavior led to unnecessary creation of identical application contexts
in the context cache for the TCF stored under different keys.
This commit ignores duplicate configuration metadata when generating
the ApplicationContext cache key (i.e., MergedContextConfiguration) in
the TCF. This is performed for the following annotations.
- @ContextConfiguration
- @ActiveProfiles (support already existed prior to this commit)
- @TestPropertySource
Specifically, if @ContextConfiguration or @TestPropertySource is
declared on a test class and its subclass or nested test class with the
exact same attributes, only one instance of the annotation will be used
to generate the cache key for the resulting ApplicationContext. The
exception to this rule is an "empty" annotation declaration. An empty
@ContextConfiguration or @TestPropertySource declaration signals that
Spring (or a third-party SmartContextLoader) should detect default
configuration specific to the annotated class. Thus, multiple empty
@ContextConfiguration or @TestPropertySource declarations within a test
class hierarchy are not considered to be duplicate configuration and
are therefore not ignored.
Since @TestPropertySource is a @Repeatable annotation, the same
duplicate configuration detection logic is applied for multiple
@TestPropertySource declarations on a single test class or test
interface.
In addition, this commit reinstates validation of the rules for
repeated @TestPropertySource annotations that was removed when support
for @NestedTestConfiguration was introduced.
Closes gh-25800
The migration from JUnit 4 assertions to AssertJ assertions resulted in
several unnecessary casts from int to long that actually cause
assertions to pass when they should otherwise fail.
This commit fixes all such bugs for the pattern `.isNotEqualTo((long)`.
Prior to this commit, two @ActiveProfiles declarations with the same
profiles but different order resulted in an identical, duplicate
ApplicationContext in the context cache in the Spring TestContext
Framework.
This commit uses a TreeSet to ensure that registered active profiles
are both unique and sorted, thereby avoiding cache misses for
semantically identical active profiles configuration on different test
classes.
Closes gh-25973
This commit makes TransactionInterceptor and TransactionAspectSupport
Coroutines aware, adapting Reactive transaction support to Coroutines.
Suspending functions returning a Flow are handled like Flux, for other
return types, they are handled like Mono.
Closes gh-23575
This commit introduces TestContextAnnotationUtils as a replacement for
MetaAnnotationUtils, with dedicated support for honoring the new
@NestedTestConfiguration annotation and related annotation search
semantics.
MetaAnnotationUtils has been reverted to its previous scope and is now
deprecated.
See gh-19930
The existing implementation was exposed to very poor performance when matching
with multiple delimiters against a large buffer with many delimiters. In that
case all matchers are invoked many times (as many as the number of delimiters)
even though some of them found no match at all on the first pass.
The revised implementation uses a single index and advances all matchers
together, checking one byte a time, and not letting any one of them search to
the end of the entire buffer on a single pass.
Closes gh-25915
Simplify and optimize the processing of the input stream.
The existing implementation was using bufferUntil and creating a List
for every line along with an EndFrameBuffer inserted for the
bufferUntil predicate. So the larger the input buffer and the more
lines it contained, the greater the overhead.
The new implementation avoids bufferUntil for all lines and
instead uses concatMapIterable to aggregate the lines from a buffer
into a single list. So the larger the input buffer and the more
lines it contains, the better the throughput. The only buffering
used then is for partial chunks and those are accumulated in a list.
See gh-25915
This commit introduces support for discovering @Sql, @SqlGroup,
@SqlConfig, and @SqlMergeMode on enclosing classes for @Nested test
classes in JUnit Jupiter.
Closes gh-25913
Includes forPayload methods and common adapter classes for programmatic usage.
Aligns default order values for event handling delegates to LOWEST_PRECEDENCE.
Closes gh-24163
Prior to this commit, references to `JsonGenerator` and
`ByteArrayBuilder` were not closed/released within codecs calls.
This prevents Jackson from reusing more efficiently shared memory
resources.
This commit properly closes/releases Jackson resources in Spring MVC,
Spring WebFlux and Spring Messaging codecs.
A benchmark on WebFlux codecs (in both single value/streaming mode)
shows significant throughput and allocation improvements for small
payloads.
Closes gh-25910
The documentation written for the method WebSocketTransportRegistration.setSendTimeLimit(int timeLimit) mentions that, if no time limit is specified, a default value of 10 seconds is used; however, later on the exact default value employed is incorrectly typed as 10 * 10000 ms, which would result in 100 seconds instead.
The javadoc has been updated in order to show the correct value in milliseconds (10 * 1000).
This commit adds new tasks to the release pipeline, generating release
notes automatically using the issues in the current milestone and
pushing that as the content of the GitHub release.
Closes gh-25922
Before this commit, ReadCompletionHandler delayed closing the channel
to allow an ongoing read to complete/fail so we can get a hold of the
associated DataBuffer and release it. This can be problematic since the
read take time to complete but even more importantly there was a race
condition where we didn't check if we've been disposed concurrently
while releasing the read flag.
This commit removes the delay and closes the channel immediately from
cancel() and that should in turn fail any ongoing read operation,
according to AsynchronousChannel, and the DataBuffer is released.
Further improvements include:
- combining the "reading" and "disposed" AtomicBoolean's into a
single "state" AtomicReference.
- an optimistic check to remain in READING mode and avoid state
switches when there is demand to continue reading.
Closes gh-25831
Prior to this commit only Propagation.NOT_SUPPORTED was supported for
disabling test-managed transactions via the `propagation` attribute of
`@Transactional`.
This commit allows users to specify Propagation.NOT_SUPPORTED or
Propagation.NEVER to disable test-managed transactions.
Closes gh-25909
This commit raises the minimum Coroutines version supported
to 1.4.0-M1 and above, and changes usages of awaitFirst() or
awaitFirstOrNull() to awaitSingle() or awaitSingleOrNull()
to fix gh-25007.
Closes gh-25914
Closes gh-25007
Prior to this commit, the EnclosingConfiguration mode used in
conjunction with @NestedTestConfiguration defaulted to INHERIT.
In other to allow development teams to change the default to OVERRIDE
(e.g., for compatibility with Spring Framework 5.0 through 5.2), this
commit introduces support for changing the default EnclosingConfiguration
mode globally via a JVM system property or via the SpringProperties
mechanism.
For example, the default may be changed to
EnclosingConfiguration.OVERRIDE by supplying the following JVM system
property via the command line.
-Dspring.test.enclosing.configuration=override
Closes gh-19930
Prior to this commit (and since Spring Framework 5.0), Spring's
integration with JUnit Jupiter supported detection of test
configuration (e.g., @ContextConfiguration, etc.) on @Nested classes.
However, if a @Nested class did not declare its own test configuration,
Spring would not find the configuration from the enclosing class. This
is in contrast to Spring's support for automatic inheritance of test
configuration from superclasses. The only workaround was to
copy-n-paste the entire annotation configuration from enclosing classes
to nested tests classes, which is cumbersome and error prone.
This commit introduces a new @NestedTestConfiguration annotation that
allows one to choose the EnclosingConfiguration mode that Spring should
use when searching for test configuration on a @Nested test class.
Currently, the options are INHERIT or OVERRIDE, where the current
default is OVERRIDE. Note, however, that the default mode will be
changed to INHERIT in a subsequent commit. In addition, support will be
added to configure the global default mode via the SpringProperties
mechanism in order to allow development teams to revert to the behavior
prior to Spring Framework 5.3.
As of this commit, inheritance of the following annotations is honored
when the EnclosingConfiguration mode is INHERIT.
- @ContextConfiguration / @ContextHierarchy
- @ActiveProfiles
- @TestPropertySource / @TestPropertySources
- @WebAppConfiguration
- @TestConstructor
- @BootstrapWith
- @TestExecutionListeners
- @DirtiesContext
- @Transactional
- @Rollback / @Commit
This commit does NOT include support for inheriting the following
annotations on enclosing classes.
- @Sql / @SqlConfig / @SqlGroup
In order to implement this feature, the search algorithms in
MetaAnnotationUtils (and various other spring-test internals) have been
enhanced to detect when annotations should be looked up on enclosing
classes. Other parts of the ecosystem may find the new
searchEnclosingClass() method in MetaAnnotationUtils useful to provide
similar support.
As a side effect of the changes in this commit, validation of user
configuration in repeated @TestPropertySource declarations has been
removed, but this may be reintroduced at a later date.
Closes gh-19930
This commit adds support for Kotlin Coroutines suspending functions to
Spring MVC, by converting those to a Mono that can then be handled by
the asynchronous request processing feature.
It also optimizes Coroutines detection with the introduction of an
optimized KotlinDetector.isSuspendingFunction() method that does not
require kotlin-reflect.
Closes gh-23611
Flow decoding is not supported yet since it depends on
kotlin/kotlinx.serialization#1073, but it will be
enabled when this issue will be fixed.
Closes gh-25771
The workaround was removed in the 5.3 milestone phase and in master
only because the referenced Jetty issue is marked fixed. However,
what we need to replace it with should be a little more involved
and also it's not entirely clear if the fixes in Jetty aligns with
our release and retain semantics so that needs to be investigated
more thoroughly.
Prior to this commit, the resource handler serving static resources for
Spring MVC and Spring WebFlux would always look at the
`Resource#lastModified` information, derive the `"Last-Modified"` HTTP
response header and support HTTP conditional requests with that
information.
In some cases, builds or packaging tools choose to set this last
modification date to a static date in the past. This allows tools to
have reproducible builds or to leverage caching given the static
resources content didn't change.
This can lead to problems where this static date (e.g. "1980-01-01") is
used literally in HTTP responses and will make the HTTP caching
mechanism counter-productive: the content of the resources changed, but
the application insists on saying it didn't change since the 80s...
This commit adds a new configuration option to disable this support -
there is no way to automatically discard those dates: there is no
standard for that and many don't use he "EPOCH 0 date" as it can lead to
compatibility issues with different OSes.
Closes gh-25845
Prior to this commit, error handlers in the WebMvc.fn and WebFlux.fn
router function builders had to be registered in an unintuitive, reverse
order, due to the filter chain composition model used.
This commit reverses the error handler order, so that more specific
error handlers can come before generic ones.
Closes gh-25541
This commit adds two overloaded methods for each HTTP method in the
WebFlux.fn and WebMvc.fn route builders: one method taking just a
handler function, the other a request predicate and handler function.
After this commit, it is no longer required to provide a String path,
which is particularly useful when nesting routes, and the path would be
"".
Closes gh-25752
This commit introduces a new async(Object) method in the WebMvc.fn,
taking a asynchronous response as argument in the form of a
CompletableFuture or Publisher. This allows for asynchronous setting
of headers and status (and not just body, which was already possible).
Closes gh-25828
Prior to this commit, the Series value for an HttpStatus was always
evaluated which resulted in an allocation of a Series array by invoking
Series.values() which makes a defensive copy.
This commit addresses this issue by hardcoding the corresponding Series
within the HttpStatus constructor, thereby avoiding any unnecessary
computations. In addition, a unit test has been added to verify that
all HttpStatus enum constants have a properly configured Series.
Closes gh-22366
The exchange() method is now deprecated because it is not safe for
general use but that doesn't apply to the WebTestClient because it
exposes a different higher level API for response handling that
ensures the response is consumed. Nevertheless WebTestClient cannot
call WebClient.exchange() any more.
To fix this WebTestClient no longer delegates to WebClient and thus
gains direct access to the underlying ExchangeFunction. This is
not a big deal because WebClient and WebTestClient do the same
only when it comes to gathering builder options and request input.
See gh-25751
This commit deprecates LiveBeansView and related classes in order to allow
a future removal in order to increase the separation of concerns between
Spring Framework and Spring Boot, and the consistency between JVM
and native.
Closes gh-25820
Now that there's a new JMH infrastructure for benchmarks and that
performance tests have been rewritten to use it, we should remove the
`PERFORMANCE` `TestGroup` to avoid introducing such tests in the future.
Closes gh-24830
Prior to this commit, some tests would belong to the PERFORMANCE
`TestGroup`, while they were not testing for performance but rather
performing functional tests that involve long running operations or
timeouts.
This commit moves those tests to the LONG_RUNNING `TestGroup`.
See gh-24830
Issues gh-25038 and gh-25618 collectively introduced a regression for
thread-scoped and transaction-scoped beans.
For example, given a thread-scoped bean X that depends on another
thread-scoped bean Y, if the names of the beans (when used as map keys)
end up in the same bucket within a ConcurrentHashMap AND an attempt is
made to retrieve bean X from the ApplicationContext prior to retrieving
bean Y, then the use of Map::computeIfAbsent in SimpleThreadScope
results in recursive access to the same internal bucket in the map.
On Java 8, that scenario simply hangs. On Java 9 and higher,
ConcurrentHashMap throws an IllegalStateException pointing out that a
"Recursive update" was attempted.
In light of these findings, we are reverting the changes made to
SimpleThreadScope and SimpleTransactionScope in commits 50a4fdac6e and
148dc95eb1.
Closes gh-25801
Prior to this commit, the `docsZip` task would not reference the new
output locations for the `asciidoctor` and `asciidoctorPdf` tasks.
This results with missing reference docs in the docs zip.
This commit updates the input locations of the Zip task to include the
produced reference docs.
Fixes gh-25783
Prior to this commit, the Asciidoctor Gradle tasks generated top-level
HTML and PDF documents for AsciiDoc files that are included in other
top-level documents. This causes slower builds and results in each
include-file being published twice:
1) inline in the including document (as intended)
2) as a top-level document but missing surrounding context (unintended)
The reason these include-files are generated as top-level documents is
that the asciidoctor and asciidoctorPdf Gradle tasks are configured to
use '*.adoc' as the input source files.
This commit addresses this issue by moving the following include-files
to new subdirectories. Locating the include-files in the subdirectories
causes them to be ignored in the '*.adoc' pattern used to identify
input source files.
- data-access-appendix.adoc -> data-access/data-access-appendix.adoc
- integration-appendix.adoc -> integration/integration-appendix.adoc
- testing-webtestclient.adoc -> testing/testing-webtestclient.adoc
Closes gh-25783
Prior to this commit, the asciidoctor Gradle task was configured to
generate both the HTML5 and PDF backends. Unfortunately, this resulted
in resources such as HTML, JavaScript, CSS, and images being published
alongside the generated PDF documents.
This commit addresses this issue by introducing the use of a dedicated
asciidoctorPdf Gradle task. The existing asciidoctor Gradle task has
been modified to only generate HTML5 output. Both of these tasks now
share common configuration supplied by the updated asciidoctorj Gradle
task.
In addition, the asciidoctor task now depends on the asciidoctorPdf
task. Thus, invoking `./gradlew asciidoctor` will still generate both
the HTML5 and PDF outputs; whereas, `./gradlew asciidoctorPdf` will
generate only the PDF outputs. We may later decide to rework the tasks
to introduce a dedicated asciidoctorHtml task so that we can generate
the HTML outputs without having to generate the PDF outputs (which are
more time consuming).
See gh-25783
Prior to this commit, the Asciidoctor Gradle tasks generated top-level
HTML and PDF documents for AsciiDoc files that are included in other
top-level documents. This causes slower builds and results in each
include-file being published twice:
1) inline in the including document (as intended)
2) as a top-level document but missing surrounding context (unintended)
The reason these include-files are generated as top-level documents is
that the asciidoctor and asciidoctorPdf Gradle tasks are configured to
use '*.adoc' as the input source files.
This commit addresses this issue by moving the following include-files
to new subdirectories. Locating the include-files in the subdirectories
causes them to be ignored in the '*.adoc' pattern used to identify
input source files.
- data-access-appendix.adoc -> data-access/data-access-appendix.adoc
- integration-appendix.adoc -> integration/integration-appendix.adoc
- testing-webtestclient.adoc -> testing/testing-webtestclient.adoc
Closes gh-25783
Prior to this commit, the asciidoctor Gradle task was configured to
generate both the HTML5 and PDF backends. Unfortunately, this resulted
in resources such as HTML, JavaScript, CSS, and images being published
alongside the generated PDF documents.
This commit addresses this issue by introducing the use of a dedicated
asciidoctorPdf Gradle task. The existing asciidoctor Gradle task has
been modified to only generate HTML5 output. Both of these tasks now
share common configuration supplied by the updated asciidoctorj Gradle
task.
In addition, the asciidoctor task now depends on the asciidoctorPdf
task. Thus, invoking `./gradlew asciidoctor` will still generate both
the HTML5 and PDF outputs; whereas, `./gradlew asciidoctorPdf` will
generate only the PDF outputs. We may later decide to rework the tasks
to introduce a dedicated asciidoctorHtml task so that we can generate
the HTML outputs without having to generate the PDF outputs (which are
more time consuming).
See gh-25783
We are passing custom values to the constructor of PooledByteBufAllocator in
tests in order to turn of caching. This is based on:
https://github.com/netty/netty/issues/5275#issuecomment-220547057
Netty 4.1.52 has significant changes in PooledByteBufAllocator:
https://github.com/netty/netty/pull/10267
After the changes, our current value for maxOrder=2, which results in
chunkSize=16K, causes an assert failure in PoolChunk where the runSize
exceeds the chunkSize.
We don't expect a browser to save error responses to a file but we
extend this protection anyway since "inline" is only a suggestion
that shouldn't have any side effects.
This commit makes sure that exceptions emitted by WebClient are wrapped
by WebClientExceptions:
- Exceptions emitted by the ClientHttpConnector are wrapped in a new
WebClientRequestException.
- Exceptions emitted after a response is received are wrapped in a
WebClientResponseException
Closes gh-23842
This is done:
- For consistency with other Spring projects
- Because it is probably a better option to use reference instead of
spring-framework-reference (spring-framework is already present in
the URL)
- To improve PDF documentation discoverability
As a consequence:
- spring-framework-reference HTML documentation is now published
under reference/html
- spring-framework-reference/pdf PDF documentation is now published
under reference/pdf
The following permanent redirect should be created before Spring
Framework 5.3.0 release:
- current/spring-framework-reference/pdf/* to current/reference/pdf/*
- current/spring-framework-reference/* to current/reference/html/*
Closes gh-25071
See reactor/reactor-core#2374
All usages of this API are in tests, which are not checking overflow or
concurrent emissions - so a simple replacement with `try***` equivalents
is fine.
This commit remove the tokenization previously used in
UriComponentsBuilder#adaptFromForwardedHeaders, in order to support
Forwarded headers that have multiple, comma-separated 'for' elements.
Closes gh-25737
Prior to this commit, the subtype suffix of a MIME type (see RFC 6839)
was not properly taken into account when checking compatibility between
MIME types.
For example, `"application/*"` was not considered as compatible with
`"application/vnd.io.spring+json"`.
This commit adds a new `MimeType#getSubtypeSuffix()` method to easily
extract the subtype suffix information. This method is then reused in
the `isCompatibleWith` implementation to better handle these cases.
Fixes gh-25350
This commit deprecates the `AppCacheManifestTransformer` implementations
since the appcache feature is being removed from the browsers.
Closes gh-25733
UrlPathHelper is often created and used without customizations or with
the same customizations. This commit introduces re-usable, instances.
Effectively a backport of commit 23233c.
See gh-25690
Prior to this commit, the `GenericApplicationContext` configured the
`AppliationStartup` on the `BeanFactory` only right before refreshing it.
Delaying this has no purpose and we should instead configure it as soon
as possible by overriding the setter method.
Closes gh-25718
Includes deprecation of JdbcUtils.extractDatabaseMetaData(DataSource, String) in favor of the now generified version of extractDatabaseMetaData(DataSource, DatabaseMetaDataCallback).
Closes gh-25681
Closes gh-25686
This commit makes several changes in both WebMvc.fn as well as
WebFlux.fn.
- ServerRequest now exposes a RequestPath through requestPath(), and
pathContainer() has been deprecated.
- The PathPredicate and PathResourceLookupFunction now respects this
RequestPath's pathInApplication() in their path-related
functionality.
- When nesting, the PathPredicate now appends the matched part of the
path to the current context path, instead of removing the matched
part (which was done previously). This has the same result: the
matched part is gone, but now the full path stays the same.
Closes gh-25270
Renaming the `tags` method to `getTags` for overall consistency, and
fixing the Javadoc to mention that this returns an immutable collection.
Closes gh-25678
MVC data class processor constructs target instance even in case of binding failure, as long as the corresponding method parameter is not marked as optional.
Closes gh-24372
Before this change messages were sent serially across sessions but
ordering is important only within a session. This leads to head of
line blocking when a session is slow to send, and also enforcement of
send buffer size and time limits is precluded because it happens at
a lower level in the transport.
This change ensures messages are held up only if there is another
from the same session is being sent. This allows messages from each
session to flow independent of other.
See gh-25581
Prior to this commit it was possible that a StartupStep was
started but never ended. This was the case when an exception
occured during bean initializing. To always call the method
regardless of the outcome, the call to StartupStep.end has
been moved to a finally block.
When an exception occurs the StartupStep is also enriched with
the exception class and message for diagnostic purposes.
See gh-22776
Closes gh-25572
PR gh-25038 introduced regressions in SimpleThreadScope and
SimpleTransactionScope in Spring Framework 5.2.7. Specifically, if a
thread-scoped or transaction-scoped bean has a dependency on another
thread-scoped or transaction-scoped bean, respectively, a
ConcurrentModificationException will be thrown on Java 11 or higher.
The reason is that Java 11 introduced a check for concurrent
modification in java.util.HashMap's computeIfAbsent() implementation,
and such a modification can occur when a thread-scoped bean is being
created in order to satisfy a dependency of another thread-scoped bean
that is currently being created.
This commit fixes these regressions by switching from HashMap to
ConcurrentHashMap for the instance maps in SimpleThreadScope and
SimpleTransactionScope.
Closes gh-25618
Provides parity with similar options in MockMvc:
- compare header using a long value
- compare header using a date/time value
- dedicated method for "Location" header (redirect)
- let Hamcrest assert a header even when missing
See gh-19647
WebTestClient is an actual client and generally it's only possible
to assert the client response (i.e. what goes over HTTP). However,
in a mock server scenario technically we have access to the server
request and response and can make those available for further
assertions.
This will be helpful for the WebTestClient integration with MockMvc
where many more assertions can be performed on the server request
and response when needed.
See gh-19647
The original behavior was to ignore the body which came with odd
warnings in the Javadoc and potential leaks that could be reported
from tests causing unnecessary concern.
This change causes the body to be released and effectively still
ignores it but minus the potential leaks.
See gh-19647
The claimRequest method was not intended to be public and couldn't
have been used since the Info type it returned was package private.
This change completely hides the Info.
See gh-19647
Prior to this commit it was possible to configure the
DefaultListableBeanFactory used by the GenericApplicationContext
created by AbstractGenericContextLoader, but it was not possible to
completely replace the bean factory.
This commit introduces a new createContext() factory method in
AbstractGenericContextLoader which indirectly allows subclasses to
supply a custom DefaultListableBeanFactory implementation to the
GenericApplicationContext.
Closes gh-25600
This is the orginal "A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container". Here's an extra word of "otherwise".
This commit declares each of the following public interfaces as a
@FunctionalInterface.
- org.springframework.context.ApplicationContextInitializer
- org.springframework.test.web.servlet.DispatcherServletCustomizer
- org.springframework.validation.MessageCodeFormatter
- org.springframework.util.IdGenerator
- org.springframework.beans.factory.config.YamlProcessor.MatchCallback
- org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher
Closes gh-25580
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build")
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
@@ -25,6 +25,10 @@ See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/w
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## Continuous Integration Builds
Information regarding CI builds can be found in the [Spring Framework Concourse pipeline](ci/README.adoc) documentation.
## Stay in Touch
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [news feed](https://spring.io/blog/category/news).
The Spring Framework is using https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io.
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x[Spring Framework 5.3.x].
=== Setting up your development environment
@@ -25,13 +26,17 @@ spring https://ci.spring.io spring-framework Wed, 25 Mar 20
----
=== Pipeline configuration and structure
The build pipelines are described in `pipeline.yml` file.
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
You'll find in this folder the following resources:
* `pipeline.yml` the build pipeline
* `parameters.yml` the build parameters used for the pipeline
* `images/` holds the container images definitions used in this pipeline
@@ -41,6 +46,7 @@ You'll find in this folder the following resources:
=== Updating the build pipeline
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
The pipeline can be deployed using the following command:
[source]
@@ -48,4 +54,4 @@ The pipeline can be deployed using the following command:
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
* Whether this environment lives within a native image.
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.