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
Prior to this commit, MockHttpServletResponse's setCharacterEncoding()
method did not update the contentType property, which violates the
Servlet 2.4 Javadoc for getContentType() and setCharacterEncoding().
This commit addresses this issue; however, some existing tests may have
to be updated as a result of this change.
For example, note how some of the tests in this commit have been
refactored to use MediaType##isCompatibleWith() instead of asserting
exact matches for the value returned by MockHttpServletResponse's
getContentType() method.
Closes gh-25536
Prior to this commit, if null values were supplied for the
RepeatableContainers or AnnotationFilter arguments to `from()` factory
methods in MergedAnnotations, certain operations would eventually
result in a NullPointerException. This is to be expected; however, the
NullPointerException is often swallowed and only logged at INFO level
with an exception message similar to the following.
> Failed to introspect annotations on org.example.MyClass: NullPointerException
In such cases, the INFO log message is not helpful in diagnosing the
problem. Furthermore, since the exception is swallowed, the desired
operation (e.g., MergedAnnotations.stream(...)) simply returns no
results.
This commit improves the user experience by eagerly asserting non-null
preconditions for required arguments in MergedAnnotations.from()
factory methods.
Closes gh-25568
This commit removes the previously deprecated classes in Spring
Framework 5.2.x. By doing so, Spring Framework now requires RSocket
1.0+.
Closes gh-25548
Since Spring Framework 5.2, @RestControllerAdvice registered with
MockMvc when using MockMvcBuilders.standaloneSetup() has no longer been
properly supported if annotation attributes were declared in the
@RestControllerAdvice annotation. Prior to 5.2, this was not an issue.
The cause for this regression is two-fold.
1. Commit 50c257794f refactored
DefaultListableBeanFactory so that findAnnotationOnBean() supports
merged annotations; however, that commit did not refactor
StaticListableBeanFactory#findAnnotationOnBean() to support merged
annotations.
2. Commit 978adbdae7 refactored
ControllerAdviceBean so that a merged @ControllerAdvice annotation
is only looked up via ApplicationContext#findAnnotationOnBean().
The latter relies on the fact that findAnnotationOnBean() supports
merged annotations (e.g., @RestControllerAdvice as a merged instance of
@ControllerAdvice). Behind the scenes, MockMvcBuilders.standaloneSetup()
creates a StubWebApplicationContext which internally uses a
StubBeanFactory which extends StaticListableBeanFactory. Consequently,
since the implementation of findAnnotationOnBean() in
StaticListableBeanFactory was not updated to support merged annotations
like it was in DefaultListableBeanFactory, we only see this regression
with the standalone MockMvc support and not with MockMvc support for an
existing WebApplicationContext or with standard Spring applications
using an ApplicationContext that uses DefaultListableBeanFactory.
This commit fixes this regression by supporting merged annotations in
StaticListableBeanFactory#findAnnotationOnBean() as well.
Closes gh-25520
This commit removes support for a standalone "L" in the
day-of-week of a cron expression, which used a locale-dependent
API to determine what the last day of the week is (Saturday or
Sunday ?).
Alternatively, we could have implement this in the exact way as Quartz
has done (i.e. treat the "L" like "SAT"), but we opted not to do that,
as having an explicit SAT or SUN is much clearer.
This commit makes sure that in CronExpression, the asterisk is only used
in a range field, and is not surrounded by unexpected characters.
Closes gh-19500
Prior to this commit, StaticListableBeanFactory.isSingleton() returned
false for singleton beans unless they were created by a FactoryBean.
StaticListableBeanFactory.isSingleton() now properly returns true for
all beans not created by a FactoryBean.
Closes gh-25522
This commit introduces support for Quartz-specific features in
CronExpression. This includes support for "L", "W", and "#".
Closes gh-20106
Closes gh-22436
Added test for Friday 13th trigger, i.e. an uncommon crontab expression.
With the new CronExpression in place, this failure does not occur
anymore.
Closes gh-21574
Added test for a fixed day-of-week and day-of-month combination.
With the new CronExpression in place, this failure does not occur
anymore.
Closes gh-13621
Prior to this commit, if a value existed at the specified JSON path but
had an incompatible type, the AssertionError thrown contained a message
stating that the value did not exist (i.e., "No Value at JSON Path"),
which was not only misleading but also technically incorrect.
This commit fixes the error message for such use cases. For example, the
AssertionError thrown in such use cases now resembles the following.
At JSON path "$.name", value <Lisa> of type <java.lang.String> cannot
be converted to type <byte[]>
Closes gh-25480
Prior to this commit, calling reset() on MockHttpServletResponse did not
reset the `charset` field to `false` which could result in the
"Content-Type" header containing `;charset=null` which in turn would
result in errors when parsing the "Content-Type" header.
This commit resets the charset field to `false` in
MockHttpServletResponse's reset() method to avoid such errors.
Closes gh-25501
Since reactor/reactor-netty#739, the `reactor-netty` module is now split
into two: `reactor-netty-core` and `reactor-netty-http`.
This commit updates the Spring Framework build accordingly.
- The compiler is configured to retain compatibility with Kotlin 1.3.
- Explicit API mode is not yet enabled but could be in the future.
- Some exceptions thrown by Kotlin have changed to NullPointerException,
see https://youtrack.jetbrains.com/issue/KT-22275 for more details.
Closes gh-24171
PR gh-25429 brought it to our attention that there was a bug in
AnnotationScanner when using a non-null class filter that filtered out
classes; however, it turns out that there is no production code that
utilizes the package-private class filtering support.
This commit therefore removes all class filtering support from
AnnotationScanner since that functionality is effectively unused.
Closes gh-25477
This commit adds a new `StartupStep` interface and its factory
`ApplicationStartup`. Such steps are created, tagged with metadata and
thir execution time can be recorded - in order to collect metrics about
the application startup.
The default implementation is a "no-op" variant and has no side-effect.
Other implementations can record and collect events in a dedicated
metrics system or profiling tools. We provide here an implementation for
recording and storing steps with Java Flight Recorder.
This commit also instruments the Spring application context to gather
metrics about various phases of the application context, such as:
* context refresh phase
* bean definition registry post-processing
* bean factory post-processing
* beans instantiation and post-processing
Third part libraries involved in the Spring application context can
reuse the same infrastructure to record similar metrics.
Closes gh-24878
In addition to the changes in
313a7836b0 to support passing on a
the underlying WebSocket message, this commits checks for its
availability.
Closes gh-25099
Prior to this commit, if the user supplied a comma-separated list such
as "en, it" as the Content-Language header value to
MockHttpServletResponse's setHeader() method, only the first language
was actually set in the response's Content-Language header (e.g., "en").
This commit ensures that all supplied content languages are set in the
response's Content-Language header.
Closes gh-25281
Prior to this commit, scanning for annotations resulted in an infinite
loop when using the INHERITED_ANNOTATIONS search strategy and a class
filter that filters out visited classes.
This commit avoids an infinite loop in AnnotationsScanner's
processClassInheritedAnnotations(...) method by skipping the current
level of the class hierarchy when the current source class has been
filtered out.
Closes gh-25429
The recently introduced support for RSocketClient in commit
7c98251142 did not expose the underlying
client in order to avoid a hard dependency on RSocket 1.1 for the time
being. However such access appears to be necessary, e.g. for Spring
Integration, where the connection needs to be established (warmed up)
ahead of actual requests.
See gh-25332
* DestinationCache is now synchronized on multiple 'destination' locks
(previously a single shared lock)
* DestinationCache keeps destinations without any subscriptions
(previously such destinations were recomputed over and over)
* SessionSubscriptionRegistry is now a
'sessionId -> subscriptionId -> (destination,selector)' map
for faster lookups
(previously 'sessionId -> destination -> set of (subscriptionId,selector)')
closes gh-24395
Prior to this commit, The "auto grow" feature in SpEL expressions only
worked for element types with a default constructor. For example, auto
grow did not work for a list of BigDecimal elements.
This commit inserts a null value in the list when no default
constructor can be found for the element type.
Closes gh-25367
Because of security and broader industry support, support for several
remoting technologies is now deprecated and scheduled for removal in
Spring Framework 6.0.
This commit deprecates the following remoting technologies:
* HTTPInvoker
* RMI
* Hessian
* JMS remoting
Other remoting technologies like EJB or JAXWS might be deprecated in the
future depending on industry support.
Closes gh-25379
Remove convenience Map that is to avoid. The only downside is that
getHandlerMethods requires a transformation but that should not be used frequently.
See gh-22961
Prior to this commit, a Profiles instance created via Profiles.of() was
not considered equivalent to another Profiles instance created via
Profiles.of() with the exact same expressions. This makes it difficult
to mock invocations of Environment#acceptsProfiles(Profiles) -- for
example, when using a mocking library such as Mockito.
This commit makes Profiles instances created via Profiles.of()
"comparable" by implementing equals() and hashCode() in ParsedProfiles.
Note, however, that equivalence is only guaranteed if the exact same
profile expression strings are supplied to Profiles.of(). In other
words, Profiles.of("A & B", "C | D") is equivalent to
Profiles.of("A & B", "C | D") and Profiles.of("C | D", "A & B"), but
Profiles.of("X & Y") is not equivalent to Profiles.of("X&Y") or
Profiles.of("Y & X").
Closes gh-25340
This commit evolves the solution from M1 by parsing and caching patterns with the
target HandlerMapping's PathPatternParser. This makes it unnecessary for callers to
be aware of pattern parsing.
Closes gh-25312
Prior to this commit, SocketUtils used System.currentTimeMillis() for
the seed for the java.util.Random instance used internally. The use of
the milliseconds value returned by currentTimeMillis() can lead to
collisions for randomly selected free ports for tests executing in
parallel on the same computer.
This commit therefore switches to System.nanoTime() for the Random seed
used in SocketUtils in an attempt to avoid such collisions for tests
executing in parallel in different JVMs on the same computer.
Closes gh-25321
This commit makes sure that the StringHttpMessageConverter reads
input with "application/*+json" as Content-Type with the UTF-8
character set.
Closes gh-25328
This commit introduces support for writing JSON with an US-ASCII
character encoding in the Jackson encoder and message converter,
treating it like UTF-8.
See gh-25322
This commit introduces a way to change the PathPatternParser used in
PathPredicates, by way of a ChangePathPatternParserVisitor. This
visitor is used by both WebFluxConfigurationSupport and
WebMvcConfigurationSupport to make sure the configured parser is used.
Closes gh-23236
PR gh-358 introduced a "scheme but no host" check in the fromHttpUrl()
method in UriComponentsBuilder, but a similar check was not added to
fromUriString() at that time.
This commit introduces a "scheme but no host" check in fromUriString()
to align with the functionality in fromHttpUrl().
Note, however that the regular expressions used to match against the
hostname or IP address are inexact and still permit invalid host names
or IP addresses. True validation of the host portion of the URI is out
of scope for this commit.
Closes gh-25334
This commit extracts a Class.getName() invocation from String
concatenation in AbstractMonitoringInterceptor to avoid an issue
related to profile pollution.
Closes gh-25324
Prior to this commit, UriComponentsBuilder.fromHttpUrl() threw an
IllegalArgumentException if the provided URL contained a fragment.
This commit aligns the implementation of fromHttpUrl() with that of
fromUriString(), by parsing a fragment and storing it in the builder.
Closes gh-25300
Using @SafeVarargs in Jackson mapper builder and factory bean classes
allows the varargs methods to be used without a compiler warning. The
implementations of these methods do not perform unsafe operations on
their varargs parameter. It is therefore safe to add this annotation.
The following two methods are changed:
- add @SafeVarargs to Jackson2ObjectMapperBuilder#modulesToInstall
and make it final
- add @SafeVarargs to
Jackson2ObjectMapperFactoryBean#setModulesToInstall and make it final
This is a backwards incompatible change as these methods now have to be
declared final. Existing subclasses that override one of these methods
will break.
Closes gh-25311
This commit removes the UndertowDataBuffer, in favor of using regular
DataBuffers from the DataBufferFactory. During the development of the
DefaultPartHttpMessageReader, it was determined that invoking various
slicing and releasing operators on the UndertowDataBuffer resulted in
memory leaks. This commit fixes that.
This commit introduces the DefaultMultipartMessageReader, a fully
reactive multipart parser without third party dependencies.
An earlier version of this code was introduced in fb642ce, but removed
again in 77c24aa because of buffering issues.
Closes gh-21659
This commit fixes a recent regression as a result of 5225a57411
with the determination of non-pattern vs pattern URLs. That in turn affects the ability to perform
direct matches by URL path.
There is also a fix in PathPattern to recognize "catch-all" patterns as pattern syntax.
See gh-24945
The following was reported after the change and is related to it:
https://github.com/reactor/reactor-netty/issues/1170. An HTTP HEAD with the body
not consumed. Connection is disposed and closed leading to subsequent request to
fail. Adding toBodilessEntity() helps.
This change does not close the connection but rather drains the body which does
not impact subsequent re-use of the connection. This however may compete with a
late subscriber actually attempting to read the response. At that point there is
little choice but to raise an ISE with a more specific description.
See gh-25216
Prior to this commit the BeanPropertyRowMapper used
String.substring and String.toLowerCase to parse the
field names. This would generate more String than needed.
Instead one could iterate over the internal char[] of the
String and use the Character methods instead. This reduces
the String creation.
Closes gh-25301
This commit ensures that when mutating `ServerHttpRequest` instances,
the original contextPath information is copied to the request being
built.
Note that mutation on the `contextPath(String)` or `path(String)` should
be reflected to the other. (See their Javadoc for more information).
Fixes gh-25279
With this commit it is no longer assumed that all charset names in the
JsonEncoding can be resolved by Charset.forName. Instead, we store the
charset name itself, rather than the Charset object.
List<T> support was added relatively late, incorrectly decoding each
part to T which means no way to decode a single part to List<T> and
thatis the most common case (vs multipart parts with the same name).
This behavior was further misaligned with Spring MVC as well as with
the behavior for T[].
Closes gh-22973
This commit removes load time weaving, CGLIB and Objenesis support
from native images.
GraalDetector has been removed for now because of
https://github.com/oracle/graal/issues/2594. It should be reintroduced
when this bug will be fixed with NativeImageDetector class name.
Closes gh-25179
As of reactor/reactor-core#2188, `DirectProcessor` variants are
deprecated. This commit replaces them with the new
`FluxIdentityProcessor` variant.
See gh-25085
Prior to this commit, the `SslInfo` would be missing for WebFlux apps
when deployed on Reactor Netty with http/2.
This commit ensures that the request adapter checks the current channel
and the parent channel for the presence of the `SslHander`.
In the case of http/2, the `SslHander` is tied to the parent channel.
Fixes gh-25278
This commit introduces a spring.xml.ignore system property
which when set to true avoid initializing XML infrastructure.
A typical use case is optimizing GraalVM native image footprint
for applications not using XML. In order to be effective, those
classes should be initialized at build time:
- org.springframework.util.DefaultPropertiesPersister
- org.springframework.core.io.support.PropertiesLoaderUtils
- org.springframework.web.servlet.function.support.RouterFunctionMapping
- org.springframework.web.client.RestTemplate
- org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
- org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
- org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
- org.springframework.http.codec.support.BaseDefaultCodecs
- org.springframework.beans.PropertyEditorRegistrySupport
Closes gh-25151
This commit introduces a spring.spel.ignore system property
which when set to true avoid initializing SpEL infrastructure.
A typical use case is optimizing GraalVM native image footprint
for applications not using SpEL. In order to be effective, those
classes should be initialized at build time:
- org.springframework.context.support.AbstractApplicationContext
- org.springframework.core.SpringProperties
- org.springframework.context.event.EventListenerMethodProcessor
Closes gh-25153
Prior to this commit, the Forwarded headers for Spring MVC and Spring
WebFlux did not support multiple prefix values for the
`"X-Forwarded-Prefix"` HTTP header.
This commit splits and processes multiple prefixes defined in the
dedicated header.
Closes gh-25254
Prior to this commit some of the default strategies defined
for the DispatcherServlet weren't included in the default
configuration for both Java and XML configuration.
The following default beans have been added to the configuration
with the name as expected by the DispatcherServlet:
- org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
- org.springframework.web.servlet.theme.FixedThemeResolver
- org.springframework.web.servlet.support.SessionFlashMapManager
- org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
Closes gh-25209
This commit introduces support for R2DBC ("Reactive Relational Database
Connectivity") with custom ConnectionFactory implementations, a
functional DatabaseClient for SQL execution, transaction management, a
bind marker abstraction database initialization utilities, and
exception translation.
Closes gh-25065
This commit introduces a change in reactive transaction semantics for
cancel signals. Canceling a subscription now rolls back a reactive transaction
to achieve a deterministic transaction outcome.
Previously, cancel signals committed a transaction which could
cause partially committed transactions depending on when the cancel happened.
With #25209, DispatcherServlet.properties loading and parsing
will be useless for most of use cases, and it requires
configuration on GraalVM native images.
The purpose of this issue to make such loading and parsing lazy,
only invoked in getDefaultStrategies() if needed.
Closes gh-25257
- The compiler is configured to retain compatibility with Kotlin 1.3.
- Explicit API mode is not yet enabled but could be in the future.
- A workaround for Gradle build is required for now, see
https://youtrack.jetbrains.com/issue/KT-39610 for more details.
- Some exceptions thrown by Kotlin have changed to NullPointerException,
see https://youtrack.jetbrains.com/issue/KT-22275 for more details.
Closes gh-24171
Prior to this commit, the JDBC KeyHolder API only supported keys of
type Number. However, a generated key can be a UUID or something else,
and developers shouldn't have to go manually through complex
collections to access it.
This commit adds a new getKeyAs(Class<T> keyType) method to the
KeyHolder API that allows the user to specify the key type.
Closes gh-24655
This commit makes sure that Jackson-based message converters and
decoders can deal with non-unicode input. It does so by reading
non-unicode input messages with a InputStreamReader.
This commit also adds additional tests forthe canRead/canWrite methods
on both codecs and message converters.
Closes: gh-25247
Prior to this commit, a change to Javadoc in any class in spring-core
would result in ALL tests in the entire test suite being re-run via the
Gradle build.
Thanks to a tip from @melix, this commit aims to ensure that the
spring-core JAR is "reproducible".
Prior to this commit, a change to Javadoc in any class in spring-core
would result in ALL tests in the entire test suite being re-run via the
Gradle build.
Thanks to a tip from @melix, this commit ensures that the spring-core
JAR is "reproducible".
Commit 4000b244ff introduced new variants for noNullElements in
org.springframework.util.Assert.
This commit adds the corresponding tests to AssertTests.
Closes gh-25239
Prior to this commit, Jaxb2XmlDecoder and XmlEventDecoder threw
XMLStreamExceptions instead of DecodingExceptions (as the Decoder
contract defines).
This commit resolves this issue.
Closes: gh-24778
Setting path variables (and making sure they are available in a
HandlerFunction) is more convenient with MockServerRequest than
having to set attributes in MockServerWebExchange.
This commit removes MockServerRequest's deprecation.
Closes gh-25087
The AspectJPrecedenceComparator was designed to mimic the precedence
order enforced by the AspectJ compiler with regard to multiple 'after'
methods defined within the same aspect whose pointcuts match the same
joinpoint. Specifically, if an aspect declares multiple @After,
@AfterReturning, or @AfterThrowing advice methods whose pointcuts match
the same joinpoint, such 'after' advice methods should be invoked in
the reverse order in which they are declared in the source code.
When the AspectJPrecedenceComparator was introduced in Spring Framework
2.0, it achieved its goal of mimicking the AspectJ compiler since the
JDK at that time (i.e., Java 5) ensured that an invocation of
Class#geDeclaredMethods() returned an array of methods that matched the
order of declaration in the source code. However, Java 7 removed this
guarantee. Consequently, in Java 7 or higher,
AspectJPrecedenceComparator no longer works as it is documented or as
it was designed when sorting advice methods in a single @Aspect class.
Note, however, that AspectJPrecedenceComparator continues to work as
documented and designed when sorting advice configured via the
<aop:aspect> XML namespace element.
PR gh-24673 highlights a use case where AspectJPrecedenceComparator
fails to assign the highest precedence to an @After advice method
declared last in the source code. Note that an @After advice method
with a precedence higher than @AfterReturning and @AfterThrowing advice
methods in the same aspect will effectively be invoked last due to the
try-finally implementation in AspectJAfterAdvice.invoke() which invokes
proceed() in the try-block and invokeAdviceMethod() in the
finally-block.
Since Spring cannot reliably determine the source code declaration
order of annotated advice methods without using ASM to analyze the byte
code, this commit introduces reliable invocation order for advice
methods declared within a single @Aspect. Specifically, the
getAdvisors(...) method in ReflectiveAspectJAdvisorFactory now hard
codes the declarationOrderInAspect to `0` instead of using the index of
the current advice method. This is necessary since the index no longer
has any correlation to the method declaration order in the source code.
The result is that all advice methods discovered via reflection will
now be sorted only according to the precedence rules defined in the
ReflectiveAspectJAdvisorFactory.METHOD_COMPARATOR. Specifically, advice
methods within a single @Aspect will be sorted in the following order
(with @After advice methods effectively invoked after @AfterReturning
and @AfterThrowing advice methods): @Around, @Before, @After,
@AfterReturning, @AfterThrowing.
The modified assertions in AspectJAutoProxyAdviceOrderIntegrationTests
demonstrate the concrete effects of this change.
Closes gh-25186
Prior to this commit we did not have tests in place to verify the status
quo for the invocation order of all advice types when declared within
a single aspect, either via the <aop:aspect> XML namespace or AspectJ
auto-proxy support.
This commit introduces such tests that demonstrate where such ordering
is broken or suboptimal.
The only test for which the advice invocation order is correct or at
least as expected is the afterAdviceTypes() test method in
ReflectiveAspectJAdvisorFactoryTests, where an AOP proxy is hand crafted
using ReflectiveAspectJAdvisorFactory without the use of Spring's
AspectJPrecedenceComparator.
See gh-25186
Before this commit, Jackson2CodecSupport and subclasses
did not check media type encoding in the supportsMimeType
method (called from canEncode/canDecode).
As a result, the encoder reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
Closes: gh-25076
Before this commit, AbstractJackson2HttpMessageConverter and subclasses
did not check media type encoding in the canRead and canWrite
methods. As a result, the converter reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
See: gh-25076
Before this commit, Jackson2CodecSupport and subclasses
did not check media type encoding in the supportsMimeType
method (called from canEncode/canDecode).
As a result, the encoder reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
Closes: gh-25076
Before this commit, AbstractJackson2HttpMessageConverter and subclasses
did not check media type encoding in the canRead and canWrite
methods. As a result, the converter reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
See: gh-25076
Prior to this commit, there was no easy way to restrict what types could
be loaded from a YAML document in subclasses of YamlProcessor such as
YamlPropertiesFactoryBean and YamlMapFactoryBean.
This commit introduces a setSupportedTypes(Class<?>...) method in
YamlProcessor in order to address this. If no supported types are
configured, all types encountered in YAML documents will be supported.
If an unsupported type is encountered, an IllegalStateException will be
thrown when the corresponding YAML node is processed.
Closes gh-25152
Prior to this commit, ExchangeStrategies custom codec's reader and
writer were not registered due to a bug in BaseCodecConfigurer.
This commit fixes this by correcting the implementation of the
DefaultCustomCodecs constructor used within BaseCodecConfigurer.
Closes gh-25149
This commit avoids duplicate addition of void.class to the temporary
primitiveTypes Set in the static initialization block in ClassUtils.
Closes gh-25128
With a recent upgrade to an early access build for JDK 15,
ServerHttpsRequestIntegrationTests began failing since Netty's
SelfSignedCertificate could not be properly initialized.
This commit adds a test fixture dependency on BouncyCastle which is now
needed by Netty's SelfSignedCertificate on JDK 15 or higher, since JDK 15
no longer supports the javax.security.cert.X509Certificate.
See: https://bugs.openjdk.java.net/browse/JDK-8241039
Prior to this commit, if attributes were configured in the builder
returned by `ServerRequest.from(...)`, those attributes were not
available in the `ServerRequest` built by the builder. In addition, any
attributes in the original `ServerRequest` supplied to
`ServerRequest.from(...)` were also ignored.
This commit addresses this issue by ensuring that the attributes
configured via DefaultServerRequestBuilder are used as the attributes
in the resulting `ServerRequest`.
This commit also polishes the Javadoc in `ServerRequest` and
`ClientResponse` and avoids the use of lambda expressions in the
constructors for `DefaultServerRequestBuilder` and
`DefaultClientResponseBuilder`.
Closes gh-25106
Prior to this commit, calling the `setResponseBodyAdvice` method would
clear all existing `ResponseBodyAdvice` instances present in the list
before adding provided one.
This behavior is inconsistent with the Javadoc and other
implementations.
This brings the method in line with the existing documentation.
See gh-24204
In many places UrlPathHelper is created and used without any
customizations, in some cases repeatedly. This commit adds a
shared read-only UrlPathHelper instance with default settings.
See gh-25100
Prior to this commit (and the previous one), the `AntPathStringMatcher`
(inner class of `AntPathmatcher`) would compile `Pattern` instances and
use regex matching even for static patterns such as `"/home"`.
This change introduces a shortcut in the string matcher algorithm to
skip the `Pattern` creation and uses `String` equality instead.
Static patterns are quite common in applications and this change can
bring performance improvements, depending on the mix of patterns
configured in the web application.
In benchmarks (added with this commit), we're seeing +20% throughput
and -40% allocation. This of course can vary depending on the number of
static patterns configured in the application.
Closes gh-24887
Prior to this commit, `MediaType.parseMediaType` would already rely on
the internal LRU cache in `MimeTypeUtils` for better performance. With
that optimization, the parsing of raw media types is skipped for cached
elements.
But still, `MediaType.parseMediaType` would first get a cached
`MimeType` instance from that cache and then instantiate a
`new MediaType(type, subtype, parameters)`. This constructor not only
replays the `MimeType` checks on type/subtyme tokens and parameters, but
it also performs `MediaType`-specific checks on parameters.
Such checks are not required, as we're using an existing `MimeType`
instance in the first place.
This commit adds a new protected copy constructor (skipping checks) in
`MimeType` and uses it in `MediaType.parseMediaType` as a result.
This yields interesting performance improvements, with +400% throughput
and -40% allocation/call in benchmarks. This commit also introduces a
new JMH benchmark for future optimization work.
Closes gh-24769
Prior to this commit, the Spring Framework test suite would rely only on
"Performance" tests associated with a specific CI build. As outlined in
gh-24830, the way they're built and executed is not working well
anymore.
This commit introduces a new JMH benchmark infrastructure in the build.
The goal here is not to run those benchmarks as part of a CI build, but
rather provide a proper infrastructure for writing and locally running
micro-benchmarks when working on specific optimizations.
This commit adds and configures a Gradle JMH plugin to allow for JMH
benchmark classes in Spring Framework modules (in `src/jmh/java` of each
`spring-*` module). It's also relaxing the checkstyle rules for JMH
classes, especially around Javadoc rules: this code is not meant to
have Javadocs.
Finally, this commit links to a new Wiki page on the project GitHub
repository documenting the infrastructure and helping contributors to
run and design benchmarks.
See gh-24830
This commit avoids invoking StringBuilder.append(Object) in favor
of explicit method calls to append(String) and append(char) in
ContentDisposition.escapeQuotationsInFilename(String).
Closes gh-25056
This commit optimizes code in ResourceBundleMessageSource
by using computeIfAbsent instead of putIfAbsent.
In addition, the content of some Javadoc has been adjusted.
Closes gh-25054
Prior to this commit, if a BeanNameAutoProxyCreator was configured with
a custom TargetSourceCreator, the TargetSourceCreator was applied to
all beans in the ApplicationContext. Thus, the list of supported
beanNames was effectively ignored when applying any
TargetSourceCreator. Consequently, if a TargetSourceCreator returned a
non-null TargetSource for a given bean, the BeanNameAutoProxyCreator
proxied the bean even if the bean name had not been configured in the
beanNames list.
This commit addresses this issue by ensuring that a custom
TargetSourceCreator is only applied to beans whose names match the
configured beanNames list in a BeanNameAutoProxyCreator.
Closes gh-24915
Prior to this commit, the `VersionResourceResolver` implementations
would write a strong ETag HTTP response header with the resolved version
of the resource (the actual value depending on the chosen strategy).
This approach doesn't work well when combined with HTTP compression.
Web servers disable HTTP response copression in the presence of strong
ETags since mutating the response body would break the contract.
This commit changes this semantic and ensures that weak ETags are used
instead.
Closes gh-24898
Prior to this commit, patterns like `"/path/**/other"` would be treated
as `"/path/*/other"` (single wildcard, i.e. matching zero to many chars
within a path segment). This will not match multiple segments, as
expected by `AntPathMatcher` users or by `PathPatternParser` users when
in patterns like `"/resource/**"`.
This commit now rejects patterns like `"/path/**/other"` as invalid.
This behavior was previously warned against since gh-24958.
Closes gh-24952
This commit picks up where 613bd3be1d
left off by ensuring that a transaction manager configured via the
TransactionManagementConfigurer API takes precedence over any
transaction manager configured as a bean in the ApplicationContext
unless @Transactional is configured with a qualifier for the explicit
transaction manager to use in tests.
Closes gh-24869
When mutating a ServerHttpRequest or ClientResponse, the respective
builders no longer access cookies automatically which causes them to
be parsed and does so only if necessary. Likewise re-applying the
read-only HttpHeaders wrapper is avoided.
See gh-24680
Given that the body is a Flux<DataBuffer> there probably could be a
Flux<DataBuffer> body();
At least bodyToFlux(DataBuffer.class) which is used when mutating and
is a common case should not incur overhead.
See gh-24680
from() has the flaw of ignoring the body and it can't be fixed because
applications are guaranteed to be setting it already and if set twice
the builder drains the first body.
mutate() is a better fit in any case for what needs to be done in a
filter chain. It can be done more efficiently and is consistent with
similar options on the server side.
See gh-24680
Native server request headers have been wrapped rather than copied
since 5.1. This commit applies the same change to the client side
where, to make matters worse, headers were copied repeatedly on every
access, see also previous commit ca897b95.
For Netty and Jetty the wrappers are the same as on the server side
but duplicated in order to remain package private.
See gh-24680
Prior to this commit, the Spring TestContext Framework (TCF) favored a
@Primary transaction manger over one configured via the
TransactionManagementConfigurer API, and this contradicts the behavior
in production Spring applications.
This commit aligns the transaction manger lookup within the TCF so that
a transaction manger configured via the TransactionManagementConfigurer
API is properly favored over a @Primary transaction manager.
Closes gh-24869
Prior to this commit, the TransactionAttributeSourceClassFilter
filtered out PlatformTransactionManager but not
ReactiveTransactionManager implementations.
TransactionAttributeSourceClassFilter now filters out any
TransactionManager implementation, covering both imperative and
reactive transaction managers.
This commit finishes the first step for migrating our complete build and
release pipeline to Concourse CI.
We're creating here a new "Release" jobs group in our pipeline.
We can now release Milestones from our pipeline with:
* the "stage-milestone" job, which creates and tags a new Milestone
version on the source repository, builds the artifacts and deploys them
in a staging repository and updates the version to the next SNAPSHOT.
* the "promote-milestone" fetches the build information from the staging
repository and promotes the released milestone in the official milestone
repository.
Interactions with the Artifactory and Bintray REST APIs are done using
the https://github.com/spring-io/concourse-release-scripts project.
Closes gh-22490
Prior to this commit, if an instance of XStreamMarshaller was used
concurrently from multiple threads without having first invoked the
afterPropertiesSet() method, the private `xstream` field could be
initialized multiple times resulting in a ConcurrentModificationException
in XStream's internal DefaultConverterLookup.
This commit fixes these concurrency issues by making the `xstream` field
volatile and by implementing a double-checked locking algorithm in
getXStream() to avoid concurrent instance creation.
Closes gh-25017
TransactionAttribute now exposes a labels attribute that associates a
descriptive array of labels with a transaction.
Labels may be of a pure descriptive nature or may get evaluated by
transaction managers to associate technology-specific behavior
with the actual transaction.
This commit introduces support for setting the
spring.test.constructor.autowire.mode property via a JUnit Platform
configuration parameter -- for example, via the
junit-platform.properties file.
Closes gh-24285
This commit makes the default ServerRequest implementation use a pre-
parsed path container, instead of parsing the path for each invocation
of pathContainer().
The `images` folder contains some files used to create the images, such
as OmniGraffle and SVG.
This commit modifies the `include` pattern to ensure that only `*.png`
files are copied from the source folder to the published reference
manual.
Since the spring-framework.png file is not used in the generated
reference manual, this commit moves the spring-framework.png file from
the src/docs/asciidoc/images folder up to the src/docs folder.
This commit ensures that the build directory exists before writing the
build scan URL to it. This is useful when the `clean` task is executed
and the build folder is gone by the time the execution is done.
See gh-22490
This commit introduces a test suite for ClientHttpConnector
implementations, as well as fixes that resolve issues identified by
these tests.
Closes gh-24941
Prior to this commit, the loadFactoryNames() and loadFactories() methods
in SpringFactoriesLoader effectively used a different default
ClassLoader.
This commit ensures that the ClassLoader for SpringFactoriesLoader.class
is now consistently used as the default ClassLoader.
Closes gh-24992
This commit ensures that the static cache in SpringFactoriesLoader
contains unmodifiable lists of unique names of factory implementations.
See gh-24985
This commit fixes the file pattern for the published zip artifacts.
Prior to this commit, the pattern was wrong and properties were not
applied to the published archives, preventing them from being published
automatically (javadoc, reference documentation, schemas...).
See gh-22490
Prior to this commit, SpringFactoriesLoader discovered all registered
factory implementations for a given factory type even if duplicates
were registered within a single META-INF/spring.factories file or in
multiple such files in the classpath.
This commit updates the internals of SpringFactoriesLoader so that
duplicate registrations are ignored, thereby aligning with the
well-known semantics for java.util.ServiceLoader in this regard.
Closes gh-24985
This commit updates the build pipeline to only run the checks
(formatting and tests) with the build when non-JDK8 variants are used
for sanity checks.
See gh-22490
- Build Scan plugin is now Gradle Enterprise plugin applied in settings
- Compile task dependencies are now defined through classpath
- Test fixture publication can be disabled through public API
Closes gh-24384
This commit adds the Concourse build infrastructure under the "ci/"
folder. It contains:
* "images/", the definitions of container images used in the pipeline
* "pipeline.yml" the build pipeline definition
* "parameters.yml" the parameters for the pipeline definition
* "tasks/" the tasks used by the build pipeline
* "scripts/" scripts used by pipeline tasks
This first iteration of the Concourse pipeline builds CI container
images for JDK8, JDK11, JDK14 and JDK15.
These images are used for building and publishing the master branch of
Spring Framework using JDK8. Other JDK variants are sanity checks and
don't actually publish the produced artifacts.
See gh-22490
As we're moving the build to Concourse CI, we don't need to use the
Artifactory plugin anymore. Our build will publish the artifacts to a
repository on the local filesystem and will push its content to
Artifactory with the spring-io/artifactory-resource.
This commit also adds the conditional configuration for publishing to a
local repository.
See gh-22490
Prior to this commit, BeanUtils.copyProperties() ignored generic type
information when comparing candidate source and target property types.
This commit reworks the implementation of BeanUtils.copyProperties() so
that generic type information is taken into account when copying
properties.
See gh-24281
This reverts commit ff65ccba3e.
Compiling against Groovy 3.0.3 currently results in the following two
warnings that cause the build to fail.
warning: Cannot find annotation method 'value()' in type 'SuppressFBWarnings': class file for edu.umd.cs.findbugs.annotations.SuppressFBWarnings not found
warning: Cannot find annotation method 'justification()' in type 'SuppressFBWarnings'
Includes consistent constructor-level storage of derived resource in ScannedGenericBeanDefinition and ConfigurationClassBeanDefinition.
Closes gh-24978
This commit moves the toString() implementation for synthesized
annotations from TypeMappedAnnotation to
SynthesizedMergedAnnotationInvocationHandler in order to take advantage
of the synthesized annotation attribute value cache introduced in
72b1abd226.
Closes gh-24970
If set parent bean factory to self, once try to get an undefined bean, bellow condition
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
...
}
will always be true and StackOverflowError will be thrown.
Sometimes, this issue is hard to detect during runtime, if self-reference is not allowed here, error will be found at the early time of startup.
Also, a self-reference parent bean factory is valueless.
Motivation
----------
The Spring MVC ModelAttributeMethodProcessor includes many helpful
extension methods that allow developers to extend and enhance the data
binding capabilities of the class. Unfortunately, Spring WebFlux's
equivalent class, the ModelAttributeMethodArgumentResolver, does not
include these same extension methods. I am leveraging these extension
methods, specifically the bindRequestParameters method, to provide
valuable enhancements to my application. I would like to provide these
same enhancements to the WebFlux portion of my application and am
unable to do so at this time. I would like to update the WebFlux
ModelAttributeMethodArgumentResolver to add the bindRequestParameters
method.
Modifications
-------------
I created a new method called bindRequestParameters and encapsulated
the WebExchangeDataBinder bind call inside of it. This method is
marked as protected as it should only be used by children of this
class. This change mirrors the behavior in the equivalent Spring MVC
class (ModelAttributeMethodProcessor).
Result
------
The WebFlux ModelAttributeMethodArgumentResolver can now accept
alternative data binding implementations mirroring the Web MVC
behavior.
Prior to the introduction of the MergedAnnotation API in Spring Framework
5.2, our SynthesizedAnnotationInvocationHandler utilized a cache for
annotation attribute values; whereas, the new
SynthesizedMergedAnnotationInvocationHandler has no such caching in
place.
Issues such as gh-24961 indicate a regression in performance caused by
the lack of such an attribute value cache. For example, the required
attribute in @RequestParam is looked up using the internal meta-model
in the MergedAnnotation API twice per request for each @RequestParam in
a given controller handler method.
This commit reintroduces the attribute value cache to avoid the
unnecessary performance overhead associated with multiple lookups of
the same attribute in a synthesized annotation. This applies not only
to direct attribute method invocations but also to invocations of
equals() and hashCode() on a synthesized annotation.
Note, however, that this commit does NOT address multiple lookups of
annotation attribute values for invocations of toString(). That behavior
currently remains unchanged in the implementation of
org.springframework.core.annotation.TypeMappedAnnotation.toString().
Closes gh-24970
Commit 31fa1569c5 introduced initial support for avoiding unnecessary
annotation synthesis in the MergedAnnotation API; however, it only
avoided synthesis for annotations that do not declare any attributes.
This commit reworks this support to avoid unnecessary annotation
synthesis for annotations that declare attributes.
Specifically, this commit introduces a new `isSynthesizable()` method
in AnnotationTypeMapping that allows the "synthesizable" flag to be
computed once and cached along with the other metadata already cached
in AnnotationTypeMapping instances. TypeMappedAnnotation now delegates
to this new method when determining whether it should synthesize an
annotation.
Closes gh-24861
As of gh-24952, `PathPatternParser` will strictly reject patterns with
`"**"` in the middle of them. `"**"` is only allowed at the end of the
pattern for matching multiple path segments until the end of the path.
Currently, if `"**"` is used in the middle of a pattern it will be
considered as a single `"*"` instead. Rejecting such cases should
clarify the situation.
This commit prepares for that upcoming change and:
* logs a warning message if such a case is used by an application
* expands the MVC and WebFlux documentation about URI matching in
general
Closes gh-24958
Prior to Spring Framework 5.2, some of our annotation utilities would
not synthesize an annotation if it was already synthesized or not
synthesizable (i.e., did not declare local aliases via @AliasFor and
did not declare attributes that could override attributes in the
meta-annotation hierarchy above the given annotation); however, we lost
most of this functionality with the introduction of the new
MergedAnnotations API.
This commit revises the implementation of createSynthesized() in
TypeMappedAnnotation so that, for invocations of
MergedAnnotation.synthesize() and indirectly for invocations of
AnnotatedElementUtils.findMergedAnnotation(), etc.:
1. An annotation that was previously synthesized will not be
synthesized again.
2. An annotation that is not "synthesizable" will not be synthesized.
For both of the above use cases, the original annotation is now
returned from createSynthesized().
Closes gh-24861
According to the Javadoc for ServletRequest's getServerName() method,
when the `Host` header is set, the server name is "the value of the
part before ':' in the Host header value ...". For a value representing
an IPV6 address such as `[::ffff:abcd:abcd]`, the enclosing square
brackets should therefore not be stripped from the enclosed IPV6
address.
However, the changes made in conjunction with gh-16704 introduced a
regression in Spring Framework 4.1 for the getServerName() method in
MockHttpServletRequest by stripping the enclosing brackets from the
IPV6 address in the `Host` header. Similarly, the changes made in
conjunction with gh-20686 introduced a regression in Spring Framework
4.3.13 and 5.0.2 in the getRequestURL() method in
MockHttpServletRequest by delegating to the getServerName() method
which strips the enclosing brackets.
This commit fixes the implementation of getServerName() so that the
enclosing brackets are no longer stripped from an IPV6 address in the
`Host` header. The implementation of getRequestURL() is therefore also
fixed.
In addition, in order to avoid a NullPointerException, the
implementations of getServerName() and getServerPort() now assert that
an IPV6 address present in the `Host` header correctly contains an
opening and closing bracket and throw an IllegalStateException if that
is not the case.
Closes gh-24916
Prior to this commit, the `MimeTypeUtils` LRUCache would maintain a
queue to track least recently used cached values. In some cases,
concurrent access could create more entries in that unbounded queue than
expected and spend a significant amount of time removing entries in that
queue (i.e. iterating over a long list of elements).
This commit ensures that recently used entries are only added to the
queue if they've been removed by the current thread, in case of
concurrent access.
Fixes gh-24886
Prior to this commit, it was unclear in the documentation that a default
constructor will be used by default for autowiring if multiple
constructors are present and none of them is annotated with @Autowired.
This commit improves the documentation in this regard.
Closes gh-24838
This commit introduces an integration test for the status quo in the
Spring TestContext Framework (TCF) for multiple transaction managers
registered as @Primary and via the TransactionManagementConfigurer API.
In Spring Framework 5.3 we will revise the transaction manager lookup in
TestContextTransactionUtils so that the transaction manager configured
via the TransactionManagementConfigurer API is favored over a @Primary
transaction manager.
See gh-24869
This commit consolidates TransactionManager lookup tests in the Spring
TestContext Framework (TCF), migrates some to JUnit Jupiter, simplifies
their implementations, and removes duplicated test cases.
This commit introduces tests for the status quo in production support
for multiple transaction managers registered as @Primary and via the
TransactionManagementConfigurer API.
See gh-24869
The following modification will also recursively traverse the directory that the symbolic link points to.
This modification is not proposed for deleteRecursively, since it can be harmful if not intended.
This modification relates to the following commit:
Consistent use of NIO.2 for file read/write interactions
Issue: SPR-15748
12114a9
The tests were doing Callable async request processing in the main
thread which was already bound (via HandlerInterceptor#preProcess).
This leads to an ISE from TransactionSynchronizationManager#bindResource
but it went unnoticed because there is no Servlet container and no
async dispatch to continue processing.
See gh-24835
This commit updates the spring-doc-resources version to 0.2.0 to get the
latest look and feel in the HTML version of the reference manual.
Closes gh-24831
Prior to this commit, the testTestLazyConnectionToRemote() method in
MBeanClientInterceptorTests expected an exception to be thrown while
attempting to access the state of a proxied MBean after the MBeanServer
had been shutdown; however, the test occasionally failed if the server
had not been properly shutdown.
Since an attempt to wait on the server to shutdown proved not to be
consistently helpful in this scenario, we are entirely removing this
check from the test.
This commit adds a section to the reference docs that explains
views live within the trust boundary of the application, and the
security implications thereof.
Closes gh-24777
Prior to this commmit, "mutipart/*" MIME types would be cached by the
`MimeTypeUtils` LRU cache. Since those MIME types are likely to have
random boundaries in them, they can waste space in the LRU cache.
This is not improving things since we're parsing them anyway.
This commit skips the caching step for all "multipart" MIME types.
Fixes gh-24767
This commit introduces a @DynamicPropertySource annotation that can be
used on methods in test classes that want to add properties to the
Environment with a dynamically supplied value.
This new feature can be used in conjunction with Testcontainers and
other frameworks that manage resources outside the lifecycle of a
test's ApplicationContext.
Closes gh-24540
Co-authored-by: Phillip Webb <pwebb@pivotal.io>
This commit improves the performance of the `ConcurrentLruCache` and
applies a consistent style to the code:
* separating read/write locks into different variables does not help
performance, so this change is reverted
* apply a consistent style for read/write locks and try/cactch calls
* the reordering of recently used keys is only done when the cache is
full
Fixes gh-24671
- manage collection size manually
- check cache hit first before size check
- reduce read-lock scope
- use `map.get` to test cache instead of `queue.remove`
Closes gh-24469
See gh-24671
This commit fixes the example by reverting the renaming of the local
Actor variable to avoid a conflict with a same-named variable already
in the current scope.
See gh-24398
Spring Framework 5.2.2 introduced a regression in
DefaultResponseErrorHandler.handleError(ClientHttpResponse)
Specifically, for use cases where the InputStream had already been
consumed by the first invocation of getResponseBody(), the second
invocation of getResponseBody() resulted in the response body being
absent in the created UnknownHttpStatusCodeException.
This commit fixes this by invoking getResponseBody() only once in
DefaultResponseErrorHandler.handleError(ClientHttpReponse) in order to
reuse the retrieved response body for creating the exception message
and as a separate argument to the UnknownHttpStatusCodeException
constructor.
Closes gh-24595
A change in `docs.gradle` in 5.2.4 resulted in distribution zip files
no longer being published to
https://repo.spring.io/release/org/springframework/spring/.
This commit fixes this by updating the `mavenContent` configuration as
suggested by @wilkinsona.
Closes gh-24605
This commit changes the way RouterFunctions registered to the builder
are composed in both WebFlux.fn and WebMvc.fn.
Prior to this commit, all routes added to the build were composed with
`reduce`.
After this commit, all routes are stored in a special router function,
allowing for more efficient execution and smaller stack traces.
Closes gh-24652
This commit changes the way two RouterFunctions are composed in
WebFlux.fn. Prior to this commit, two were composed with
`switchIfEmpty()`, switching from the first to the second route if the
first did not provide an element.
After this commit, two router functions are compose using `concat`,
which results in a smaller stack trace.
See gh-24652
Credentials are not enabled by default contrary to the javadocs.
The credentials support must be enabled via #allowCredentials.
Closes gh-24691
Co-authored-by: Martin Dindoffer <martin.dindoffer@sigp.eu>
This commit adds the checkNotModified method to ServerRequest in both
WebFlux.fn and WebMvc.fn. Unlike other checkNotModified methods found
in the framework, this method does not return a boolean, but rather
a response wrapped in a Mono/Optional. If the resource has
not been changed, the not-modified response can be returned directly;
if the resource has changed, the user can create a corresponding
response using switchIfEmpty/orElse(Get).
Closes gh-24173
These calls were added in error when trying to fix#22797 and #23775.
They are not needed in 304 scenarios. Those have no response content and
are skipped by ShallowETagHeaderFilter based on the status.
This leaves disableContentCaching invoked only in streaming scenarios,
which was the original intent and should be the only reason for that
method.
See gh-24635
Prior to this commit, DefaultParameterNameDiscoverer did not register
any discovers when compiling or running as a GraalVM native image.
This commit relaxes the GraalVM check so that it is only applied to the
registration of KotlinReflectionParameterNameDiscoverer.
Consequently, StandardReflectionParameterNameDiscoverer and
LocalVariableTableParameterNameDiscoverer are once again always
registered by DefaultParameterNameDiscoverer.
Closes gh-24600
This commit adds two new properties to the `ReactorResourceFactory`.
This allows to configure the quiet and timeout periods when shutting
down Reactor resources. While we'll retain Reactor Netty's default for
production use, this option is useful for tests and developement
environments when developers want to avoid long waiting times when
shutting down resources.
Fixes gh-24538
Jackson's asynchronous parser does not support any encoding except UTF-8
(or ASCII). This commit converts non-UTF-8/ASCII encoded JSON to UTF-8.
Closes gh-24489
The attribute was previously removed only before exception resolution
in the DispatcherServlet in order to allow error rendering to make an
independent choice on content negotation.
However, Boot rendering happens later in an ERROR dispatch which could
also be a nested dispatch on some servers. So the attribute must also
generally be removed prior to mapping.
We also move the methods where this is done to the base
RequestMappingInfoHandlerMapping class which also deals with the
produces condition and where the producible attribute is added in the
first place.
Closes gh-24466
Even thought Tomcat and Jetty, which commit the response more lazily,
were not impacted by this issue, it still makes sense for them to
complete the WebFlux response (and pre-commit actions) at the same time
as for other servers for consistent behavior.
See gh-24475
Prior to this commit, spring-aspects would consider spring-orm as a
module providing aspects, which is not the case (anymore).
This commit removes that dependency as a result.
Fixes gh-24491
Prior to this commit, some WebSocket `RequestUpgradeStrategy` reactive
implementations would prevent the application from writing HTTP headers
and cookies to the response.
For Reactor Netty and Undertow, handling the upgrade and starting the
WebSocket communication marks the response status and headers as sent
and the application cannot update HTTP response headers after that.
This commit ensures that the `RequestUpgradeStrategy` implementations
mark the responses as "complete", so that headers are written before we
delegate to the server implementation.
Fixes gh-24475
Spring Framework 5.1.8 introduced a regression for the compilation of
SpEL expressions referencing a method declared in an interface. An
attempt to compile such an expression resulted in a
SpelEvaluationException caused by an IncompatibleClassChangeError.
This commit fixes this regression by adding explicit support in
ReflectivePropertyAccessor.OptimalPropertyAccessor.generateCode() for
methods declared in interfaces.
Closes gh-24357
Setting `options.fork = true` causes the classpath in the forked
compiler process to include Class-Path entries from MANIFEST.MF files
in JARs in the classpath, which results in warnings about missing
classpath entries.
This commit removes the `options.fork = true` declaration and further
simplifies the script.
See gh-24474
Spring Framework 5.0 introduced a regression in ASM-based annotation
processing. Specifically, nested annotations were no longer supported,
and component scanning resulted in an exception if a candidate
component was annotated with an annotation that contained nested
annotations.
This commit fixes this regression by introducing special handling in
AnnotationTypeMapping that supports extracting values from objects of
type TypeMappedAnnotation when necessary.
Closes gh-24375
This is a follow-up on the earlier commit
28a95e89f3 eliminating windowUntil
entirely which generates a BubblingException wrapper. This also keeps
the chain a little simpler.
See gh-24355
This commit makes the Jackson2Tokenizer enable
TokenBuffer.forceUseOfBigDecimal if the element type given to the
Decoder is BigDecimal. Previous to this commit, values would be
converted to floats.
Closes gh-24479
0.4.0 provides built-in support for remembering a user's selections
using local storage. This replaces the custom switch language
JavaScript.
The selection is stored using a key derived from the
options that were available. Concretely, when the options are Java or
Kotlin, the local storage key is java-kotlin. Similarly, if the
choices were Java, Kotlin, and XML, the key would be java-kotlin-xml.
Given local storage's domain and protocol scoping, the nature of the
key that's used for storage will allow a user's selections to be
applied across all documentation hosted on https://docs.spring.io that
offer the same options.
Closes gh-24481
After this commit, Jackson2Tokenizer honours ObjectMapper's
DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS feature when creating
TokenBuffers.
Closes gh-24479
Prior to this commit, the "-Werror" was removed as a command-line
argument in order not to fail the build for missing classpath elements.
This commit reinstates "-Werror" and removes "-Xlink:path" in order to
explicitly ignore warnings for missing classpath elements when executing
the build with a custom JAVA_HOME.
See gh-24474
This commit adds support for the following two JVM system properties
that control the Gradle build for alternative JDKs (i.e., a JDK other
than the one used to launch the Gradle process).
- customJavaHome: absolute path to the alternate JDK installation to
use to compile Java code and execute tests. Setting this system
property causes Groovy 3.0 RC3 to be used instead of 2.5.x. This
system property is also used in spring-oxm.gradle to determine
whether JiBX is supported.
- customJavaSourceVersion: Java version supplied to the `--release`
command line flag to control the Java source and target compatibility
version. Supported versions include 9 or higher. Do not set this
system property if Java 8 should be used.
Examples:
./gradlew -DcustomJavaHome=/opt/java/jdk-14 test
./gradlew --no-build-cache -DcustomJavaHome=/opt/java/jdk-14 test
./gradlew -DcustomJavaHome=/opt/java/jdk-14 -DcustomJavaSourceVersion=14 test
See gh-24474
This commit updates BeanFactoryAwareGeneratorStrategy to extend
ClassLoaderAwareGeneratorStrategy in order to avoid duplication of the
common generate() implementation.
Closes gh-24396
As per the Javadoc of ConcurrentHashMap its computeIfAbsent
implementation is atomic and hence already synchronized internally,
so we can remove the surrounding synchronization block.
See gh-24470
Spring Framework provides two implementations of the
CommandLinePropertySource API: SimpleCommandLinePropertySource and
JOptCommandLinePropertySource.
Prior to this commit, JOptCommandLinePropertySource supported empty
values for optional arguments; whereas, SimpleCommandLinePropertySource
did not.
This commit modifies the implementation of SimpleCommandLinePropertySource
to allow empty values for optional arguments.
Closes gh-24464
Hi guys,
We're facing an issue in our application when we try to call a procedure in Informix database,
our app uses standard JDBC (spring-jdbc and com.ibm.informix.jdbc.4.50.3) without Hibernate
to connect to the database
Issue:
When we trying to execute any procedure call in our Informix database there is no data returned.
Diagnostic:
It points to the Java class called CallMetaDataProviderFactory in spring-jdbc project.
Taking a look of this class there is no explicit support for Informix procedure calls, so I added "Informix Dynamic Server" to the
list of supported databases and now I can execute procedures call without issues.
Basically I added the line "Informix Dynamic Server" to the list called "supportedDatabaseProductsForProcedures"
of CallMetaDataProviderFactory class in my local environment and it worked as expected.
I really appreciate any feedback/suggestion for this approach due we would like to continue using the framework
normally in our development without losing updates using a workaround in our end.
Many thanks in advance.
We used ConnectionProvider#elastic only to customize the name. Now that
Reactor Netty's TcpResources itself uses fixed 500 by default, we
update to have the same value which would apply when global resources
are not used.
Closes gh-24424
This commit deprecates PathExtensionContentNegotiationStrategy and
ServletPathExtensionContentNegotiationStrategy and also updates code
that depends on them internally to remove that dependence.
See gh-24179
ContentNegotiationManagerFactoryBean now ensures that
ContentNegotiationManager contains the MediaType mappings even if the
path extension and the parameter strategies are off.
There are also minor fixes to ensure the media type mappings in
ContentNegotiationManagerFactoryBean aren't polluted when mapping keys
are not lowercase, and likewise MappingMediaTypeFileExtensionResolver
filters out duplicates in the list of all file extensions.
See gh-24179
Before this commit, the AbstractJackson2Encoder instantiated a
ObjectWriter per value. This is not an issue for single values or
non-streaming scenarios (which effectively are the same, because in the
latter values are collected into a list until offered to Jackson).
However, this does create a problem for SMILE, because it allows for
shared references that do not match up when writing each value with a
new ObjectWriter, resulting in errors parsing the result.
This commit uses Jackson's SequenceWriter for streaming scenarios,
allowing Jackson to reuse the same context for writing multiple values,
fixing the issue described above.
Closes gh-24198
As of gh-21783, Spring WebFlux uses a `TomcatHeadersAdapter`
implementation to directly address the native headers used by the
server.
In the case of Tomcat, "Content-Length" and "Content-Type" headers are
processed separately and should not be added to the native headers map.
This commit improves the `HandlerAdapter` implementation for Tomcat and
removes those headers, if previously set in the map. The adapter
already has a section that handles the Tomcat-specific calls for such
headers.
Fixes gh-24361
Previously, anyone could publish a scan and publishing was performed
if the GRADLE_ENTERPRISE_URL environment variable was set.
ge.spring.io has now been locked down to prohibit anonymous build scan
publishing. This commit aligns with this change by only attempting to
publish a build scan when authenticated with the server.
Authentication is achieved via an access token that is made available
via an environment variable on CI and locally via a file in ~/.gradle.
One can obtain an access key by running the following command:
./gradlew provisionGradleEnterpriseAccessKey
Closes gh-24371
The case of one data buffer containing multiple lines can could cause
a buffer leak due to a suspected issue in concatMapIterable. This
commit adds workarounds for that until the underlying issue is
addressed.
Closes gh-24339
This commit updates CORS support in order to check Origin header
in CorsUtils#isPreFlightRequest which does not change how Spring
MVC or WebFlux process CORS request but is more correct in term
of behavior since it is a public API potentially used in another
contexts.
It also removes an unnecessary check in
AbstractHandlerMethodMapping#hasCorsConfigurationSource and processes
every preflight request with PreFlightHandler.
Closes gh-24327
When a request is mapped through a producible condition on an
@RequestMapping, then a failure to find a converter/decoder should be
a 500 because the return type + media type pair were declared by the
controller and that should be possible to render.
Closes gh-23287
Previously, the Asciidoctor task was not cacheable and generating the
PDF documentation was very slow. To improve build times, the PDF
documentation was not generated for snapshot builds.
The upgrade to 2.4.0 of the Asciidoctor Gradle pluging means that the
Asciidoctor task is now cacheable. As such, its tasks will only run
when the documentation has changed. This should allow PDF
documentation to be published for every build without slowing things
down too much and the cost of generating the documentation will only
be incurred when there is a change to the documentation.
See gh-24216
This commit updates the build to use the latest version of the
Asciidoctor Gradle Plugin. One significant new feature is that the
plugin's tasks are now cacheable.
Closes gh-24216
Prior to this commit, Spring offered two top-level implementations of
the BeanNameGenerator strategy: DefaultBeanNameGenerator and
AnnotationBeanNameGenerator. The latter is used as the default bean
name generator for beans picked up via component scanning. In a typical
application, this strategy works well; however, if multiple component
scanned beans have the same simple class name (i.e., identical names
ignoring the package), a BeanDefinitionStoreException is thrown.
To address such naming conflicts, users of Spring have had to implement
a custom BeanNameGenerator based on the fully qualified class name of
such components.
Similar conflicts can arise with components registered via
configuration class imports (i.e., via @Import), and
ConfigurationClassPostProcessor addresses this via an anonymous inner
class that extends AnnotationBeanNameGenerator but falls back to using
the fully qualified class name if an explicit bean name is not provided
via an annotation.
This commit extracts the implementation of
ConfigurationClassPostProcessor's internal BeanNameGenerator into a new
top-level FullyQualifiedAnnotationBeanNameGenerator class that can be
used to disambiguate between same-named components residing in
different packages that are picked up via component scanning. This bean
name generator can be configured via @ComponentScan's nameGenerator
attribute.
Closes gh-24114
This commit merges the implementations of getCallableInterceptors()
and getDeferredResultInterceptors() in order to remove code duplication.
Closes gh-24305
Prior to this commit, when WebFlux handlers added `"Content-*"` response
headers and an error happened while handling the request, all those
headers would not be cleared from the response before error handling.
This commit clears those headers from the response in two places:
* when invoking the handler and adapting the response
* when writing the response body
Not removing those headers might break HTTP clients since they're given
wrong information about how to interpret the HTTP response body: the
error response body might be very different from the original one.
Fixes gh-24238
Prior to this series of commits, the Spring Framework build used a
custom TestSourcesPlugin to share test utilities and fixtures between
projects. This plugin served its purpose; however, it also had its
drawbacks:
- All test code was visible in all other (downstream) projects, and that
made it too easy to introduce unnecessary coupling. For example,
this made it more difficult to migrate to JUnit Jupiter.
This commit addresses such issues by migrating to Gradle's first-class
support for "Java test fixtures".
- Having test fixture code in a dedicated source folder makes it
readily apparent that the code is reused across the test suite.
- The build is now much cleaner since projects explicitly declare that
they rely on specific test fixtures of upstream projects.
- Incremental builds are now much faster on average since downstream
projects no longer have to be recompiled due to changes in tests in
upstream projects.
- Prior to these commits we effectively had around 20 test fixture
dependencies. With these commits we effectively now have only 7 test
fixture dependencies (i.e., projects that share test fixtures).
Closes gh-23550
Prior to this commit, WebFlux application would keep the quality
parameter from the "Accept" request header when selecting a media type
for the response. It would then echo it back to the client.
While strictly not wrong, this is unnecessary and can confuse HTTP
clients. This commit aligns WebFlux's behavior with Spring MVC.
Fixes gh-24239
Add a note on encoding for query parameters specifically mentioning the
"+" sign and a link to the reference docs.
Also remove duplicate Javadoc in UriComponentsBuilder which is already
inherited from UriBuilder.
The converter now tries to keep reading from the same InputStream which
should be possible with ordered and non-overlapping regions. When
necessary the InputStream is re-opened.
Closes gh-24214
Using Consumer<ClientCodecConfigurer> instead of
Consumer<ExchangeStrategies> eliminates one level of nesting that is
also unnecessary since codecs are the only strategy at present.
Closes gh-24124
The new register methods replace the now deprecated
encoder, decoder, reader, and writer methods, and also offer a choice
to opt into default properties such maxInMemorySize, if configured.
See gh-24124
Prior to Spring Framework 5.2, most annotation search algorithms made
use of AnnotationUtils.handleIntrospectionFailure() to handle exceptions
thrown while attempting to introspect annotation metadata. With the
introduction of the new MergedAnnotation API in Spring Framework 5.2,
this exception handling was accidentally removed.
This commit introduces the use of handleIntrospectionFailure() within
the new MergedAnnotation internals in order to (hopefully) align with
the previous behavior.
Closes gh-24188
Prior to this commit, when searching for annotations using the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES strategy an exception could be
thrown while attempting to load the enclosing class (e.g., a
NoClassDefFoundError), thereby halting the entire annotation scanning
process.
This commit makes this search strategy defensive by logging exceptions
encountered while processing the enclosing class hierarchy instead of
allowing the exception to halt the entire annotation scanning process.
The exception handling is performed by
AnnotationUtils.handleIntrospectionFailure() which only allows an
AnnotationConfigurationException to propagate.
See gh-24136
Prior to this commit, the enclosing class was always eagerly loaded
even if the annotation search strategy was not explicitly
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES.
See gh-24136
This commit restores the interpretation of JSON as UTF-8 by default that
was removed in #bc205e0 and also ensures a charset is not appended
automatically to "application/json".
Closes gh-24123
Given the following improperly configured composed @RequestMapping
annotation:
@Retention(RetentionPolicy.RUNTIME)
@RequestMapping
@interface PostApi {
@AliasFor("value")
String[] path() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "path")
String[] value() default {};
}
Prior to this commit, an attempt to process the above annotation
resulted in an exception similar to the following, which is not
especially helpful to discern the problem.
> Attribute 'value' in annotation [PostApi] must be declared as an
> @AliasFor 'path', not 'path'.
This commit improves the exception message for such scenarios,
resulting in an exception message similar to the following.
> Attribute 'value' in annotation [PostApi] must be declared as an
> @AliasFor attribute 'path' in annotation [PostApi], not attribute
> 'path' in annotation [RequestMapping].
Closes gh-24168
Spring Framework 5.2 introduced support for caching @ControllerAdvice
beans; however, this caching was also applied incorrectly to
non-singleton beans.
This commit addresses this regression by only caching singleton
@ControllerAdvice beans.
Closes gh-24157
Update `ResolvableType` so that variable referenced can be resolved
against wildcard types. Prior to this commit, given a type:
Map<String, ? extends List<? extends CharSequence>>
Calling `type.getGeneric(1).asCollection().resolveGeneric()` would
return `null`. This was because the `List` variable `E` referenced a
wildcard type which `resolveVariable` did not support.
Closes gh-24145
Spring Framework 5.2 introduced a regression for implicit aliases
declared via @AliasFor. Specifically, Spring's merged annotation
algorithms stopped honoring default values for implicit alias pairs if
the composed annotation was used without specifying the aliased
attributes.
This commit fixes this regression.
Closes gh-24110
As a follow-up of gh-23961, this change provides a way for custom codecs
to align with the default codecs' behavior on common features like
buffer size limits and logging request details.
Closes gh-24118
Co-authored-by: Rossen Stoyanchev <rstoyanchev@pivotal.io>
Prior to this commit, developers could configure their WebClient to use
their custom `ExchangeStrategies`, by providing it in the
`WebClient.Builder` chain.
Once created, an `ExchangeStrategies` instance is not mutable, which
makes it hard for further customizations by other components. In the
case of the reported issue, other components would override the default
configuration for the codecs maxInMemorySize.
This commit makes the `ExchangeStrategies` mutable and uses that fact to
further customize them with a new `WebClient.Builder#exchangeStrategies`
`Consumer` variant. This commit is also deprecating those mutating
variants in favor of a new `WebClient.Builder#exchangeStrategies` that
takes a `ExchangeStrategies#Builder` directly and avoids mutation issues
altogether.
Closes gh-23961
Prior to this commit, developers could configure their WebClient to use
their custom `ExchangeStrategies`, by providing it in the
`WebClient.Builder` chain.
Once created, an `ExchangeStrategies` instance is not mutable, which
makes it hard for further customizations by other components. In the
case of the reported issue, other components would override the default
configuration for the codecs maxInMemorySize.
This commit makes the `ExchangeStrategies` mutable and uses that fact to
further customize them with a new `WebClient.Builder#exchangeStrategies`
`Consumer` variant. This commit is also deprecating those mutating
variants in favor of a new `WebClient.Builder#exchangeStrategies` that
takes a `ExchangeStrategies#Builder` directly and avoids mutation issues
altogether.
Closes gh-23961
Previously, the remote build cache was only enabled if the
GRADLE_ENTERPRISE_URL environment variable was configured. This meant
that contributors would not benefit from the build time improvements
of the caching without some additional setup.
This commit updates the buildCache configuration so that reading from
the remote build cache at https://ge.spring.io is enabled for all.
Pushing to the cache continues to be disabled unless the required
credentials are provided. Build scan configuration has also been
updated in line with this change. While the server URL is now
hardcoded, publishing is still opt-in via an environment variable.
The exact mechanism by which someone can opt in will change in the
future once some server-side changes have been made. At this point,
only a change to publishAlwaysIf should be necessary.
Closes gh-24105
Spring Framework 5.2 introduced a regression in reflection-based
AnnotationMetadata. Specifically, as of 5.2, StandardAnnotationMetadata
no longer found @Inherited annotations from superclasses.
This commit fixes this regression by switching to the INHERITED_ANNOTATIONS
SearchStrategy when creating the MergedAnnotations used within
StandardAnnotationMetadata,
Note, however, that the discrepancy between StandardAnnotationMetadata
and SimpleAnnotationMetadata (i.e., reflection-based vs. ASM-based)
regarding @Inherited support still remains as it was prior to Spring
Framework 5.2.
Closes gh-24077
This commit introduces failing assertions that are currently disabled
via a boolean reproduceGh24077 flag.
Setting that flag to true demonstrates the regression for
StandardAnnotationMetadata and inconsistencies for SimpleAnnotationMetadata.
See gh-24077
This commit lowers the level of Throwable handling in parts of
spring-websocket which now handle Exception instead and allow any Error
to propagate.
Closes gh-24075
This commit exposes the method that returns the media type used to write
forms. By default, it includes the charset in the content type, which
can cause issues with certain consumers. This commit changes the method
from a private to a protected method, so that users can override the
default behavior.
Closes: gh-22971
Fix uncommon case in Jackson2SmileDecoder, where a null token,
incicating a document separator in streaming mode, is followed by
NOT_AVAILABLE.
Closes gh-24009
This commit refines Coroutines annotated controller support
by considering Kotlin Unit as Java void and using the right
ReactiveAdapter to support all use cases, including suspending
functions that return Flow (usual when using APIs like WebClient).
It also fixes RSocket fire and forget handling and adds related tests
for that use case.
Closes gh-24057
Closes gh-23866
Before this commit the connector waited for a completed response (via
ServerHttpResponse#setComplete or ServerHttpResponse#writeWith) or an
error signal in handling, but it didn't deal explicitly with the case
where both can occur.
This commit explicitly waits for the completion of handling (success
or error) before passing the response downstream. If an error occurs
after response completion, it is wrapped in a dedicated exception that
also provides access to the completed response.
Close gh-24051
This commit allows single-value async producers for the values of
metadata entries in both the SETUP and for requests. The same is also
enabled for data in the SETUP frame.
Close gh-23640
Prior to this commit, methods in a @ControllerAdvice bean were
registered and invoked twice if the advice was a scoped bean (e.g.,
request or session scoped). In other words, both the proxy bean and the
target bean were wrapped in ControllerAdviceBean instances.
This commit fixes this bug by modifying the findAnnotatedBeans() method
in ControllerAdviceBean so that it filters out targets of scoped
proxies.
Closes gh-24017
Spring Framework 5.2 introduced support for implementing the Ordered
interface in a @ControllerAdvice bean. This support requires that
@ControllerAdvice beans be eagerly resolved from the BeanFactory in
order to invoke the getOrder() method defined in the Ordered interface.
Unfortunately doing so resulted in a regression in that an attempt to
eagerly resolve a scoped @ControllerAdvice bean throws a
BeanCreationException due to the lack of an active scope (e.g., request
or session scope).
This commit fixes this regression by avoiding eager resolution of scoped
@ControllerAdvice beans. As a direct consequence, the Ordered interface
is not supported for scoped @ControllerAdvice beans.
Closes gh-23985
Before this change an @MessageMapping could be matched to any RSocket
interaction type, which is arguably too flexible, makes it difficult to
reason what would happen in case of a significant mismatch of
cardinality, e.g. request for Fire-And-Forget (1-to-0) mapped to a
method that returns Flux, and could result in payloads being ignored,
or not seen unintentionally.
This commit checks @ConnectMapping method on startup and rejects them
if they return any values (sync or async). It also refines each
@MessageMapping to match only the RSocket interaction type it fits
based on the input and output cardinality of the handler method.
Subsequently if a request is not matched, we'll do a second search to
identify partial matches (by route only) and raise a helpful error that
explains which interaction type is actually supported.
The reference docs has been updated to explain the options.
Closes gh-23999
This commit adds support for Continuation parameter that is now
considered as an optional parameter since it is never provided by
the user.
It also simplifies and optimizes the implementation.
Closes gh-23991
Prior to this commit, InstantFormatter was able to properly serialize
an Instant that is far in the future (or in the past), but it could not
properly deserialize it, because in such scenarios an ISO-formatted
Instant starts with a +/- sign.
This commit fixes this issue, while maintaining the previous contract,
and also introduces tests for InstantFormatter.
Closes gh-23895
Prior to this commit, the schemaZip Gradle task failed to find Spring
schema files on MS Windows due to path separators hard coded to forward
slashes that are not compatible with the Windows operating system.
Consequently, a full build failed on Windows since the distZip task was
not able to locate the zipped schema archive that the schemaZip task
failed to create.
This commit fixes this by updating the schemaZip task to search for
schema files using backslashes as well as forward slashes.
Closes gh-23933
Currently, if you have an optional event listener (via a @Bean method returning `null`)
this causes the event multicaster to explode violently. Now, we just safely skip it.
Previously, spring-webmvc and spring-webflux both contained tests
that would create gzipped files, write them to the filesystem
alongside the project's compiled test classes, and configure them to
be deleted on JVM exit. The output location placed the files on the
classpath, polluting it for every subsequent test that used the same
ClassLoader. The test-sources plugin combined with Gradle's use of
worker JVMs, broadens the scope of this pollution to other, downstream
projects in the same build. For example, the tests for
spring-websocket will have a different classpath depending on whether
or not the tests for spring-webmvc have already been run on the same
worker as part of the current build.
This commit updates the spring-webmvc and spring-webflux modules to
introduce a new JUnit Jupiter extension, GzipSupport. This extension
allows gzipped files to be created via an injectable GzippedFiles
class and automatically deletes each created file in an after-each
callback. This ensures that a gzipped file only exists on the
classpath for the duration of the test that needs it, avoiding the
pollution of the classpath of any subsequent tests.
Closes gh-23970
Changes introduced in commit 9b2087618b
caused a regression for Cookie support in MockHttpServletResponse.
Specifically, an Expires attribute that cannot be parsed using
`ZonedDateTime.parse()` now results in an exception; whereas,
previously an entry such as `Expires=0` was allowed.
This commit fixes this issue in MockCookie by catching and ignoring any
DateTimeException thrown while attempting to parse an Expires attribute.
Closes gh-23911
Prior to this commit, the TestGroup.CI enum constant was only used in a
single test method in spring-core. In order to enable that test, the
`testGroups` JVM system property was configured for the
Publication-master CI build plan; however, the `testGroups` system
property is not set when executing local builds. Consequently, there
has been a Gradle cache miss for every `test` task when building
something locally that's already been built on the CI server.
This commit addresses this issue by removing the `TestGroup.CI` enum
constant. The `-PtestGroups=ci` command line configuration for the
Publication-master CI build plan has also been removed on the CI server.
Closes gh-23918
This commit refactors several tests to use SocketUtils to find an
available port, compose a custom JMX service URL using that port, and
start an MBeanServer for the particular test using that port.
This commit also makes other changes to MBeanServer related tests in an
effort to make them more robust when executed concurrently.
Closes gh-23699
Prior to this commit, the `DateFormatterRegistrar` would register the
annotation-based formatter before the pattern-based formatter. This
would create an issue when an application tries to convert a `String` to
an annotated `@DateTimeFormat Date`: since the converters are considered
in reversed order of registration in
`GenericConversionServicei#ConvertersForPair`, the pattern-based variant
would always be considered before the annotation-based variant,
overriding the developer's opinion.
This commit aligns the `DateFormatterRegistrar` with the
`DateTimeFormatterRegistrar` and registers the annotation-based variant
last.
Closes gh-23893
Prior to this commit, if MockServletContext was configured with a
FileSystemResourceLoader, invocations of the following methods on a
Microsoft Windows operating system resulted in an InvalidPathException
if the supplied path contained a colon (such as "C:\\temp"). This is
inconsistent with the behavior on non-Windows operating systems. In
addition, for comparable errors resulting in an IOException, those
methods (except getRealPath()) return null instead of throwing the
exception.
- getResourcePaths()
- getResource()
- getResourceAsStream()
- getRealPath()
This commit makes handling of InvalidPathException and IOException
consistent for these methods: both exceptions now result in null be
returned by these methods.
Closes gh-23717
Previously, the infrastructure provided by WebMvcConfigurationSupport
and WebFluxConfigurationSupport can lead to unexpected results due to
the lack of qualifier for certain dependencies. Those configuration
classes refer to very specific beans, yet their injection points do not
define such qualifiers. As a result, if a candidate exists for the
requested type, the context will inject the existing bean and will
ignore a most specific one as such constraint it not defined. This can
be easily reproduced by having a primary Validator whereas a dedicated
"mvcValidator" is expected. Note that a parameter name is in no way a
constraint as the name is only used as a fallback when a single
candidate cannot be determined.
This commit provides explicit @Qualifier metadata for such injection
points, renaming the parameter name in the process to clarify that it
isn't relevant for the proper bean to be resolved by the context.
Closes gh-23887
A ResponseStatus exception now exposes extra method to return headers
for the response. This is used in ResponseStatusExceptionHandler to
apply the headers to the response.
Closes gh-23741
Prior to this commit and following changes done in d27b5d0, the CORS
response headers would not be added for SockJS-related requests, even
though a CORS configuration had been applied to SockJS/WebSocket.
This was due to a missing case in our implementation: calling
`AbstractHandlerMapping#getHandlerInternal` can return a Handler
directly, but also a `HandlerExecutionChain` in some cases, as explained
in the Javadoc.
This commit ensures that, when checking for existing CORS configuration,
the `AbstractHandlerMapping` class also considers the
`HandlerExecutionChain` case and unwraps it to get the CORS
configuration from the actual Handler.
Fixes gh-23843
- Add maxInMemorySize property to Decoder and HttpMessageReader
implementations that aggregate input to trigger
DataBufferLimitException when reached.
- For codecs that call DataBufferUtils#join, there is now an overloaded
variant with a maxInMemorySize extra argument. Internally, a custom
LimitedDataBufferList is used to count and enforce the limit.
- Jackson2Tokenizer and XmlEventDecoder support those limits per
streamed JSON object.
See gh-23884
At present, MockCookie doesn't preserve expires attribute. This has a
consequence that a cookie value set using
MockHttpServletResponse#addHeader containing an expires attribute will
not match the cookie value obtained from
MockHttpServletResponse#getHeader, since the expires attribute will get
calculated based on current time.
This commit enhances MockCookie to preserve the expires attribute.
Closes gh-23769
This commit provides opt-in enablement of Gradle's remote build
cache. When the GRADLE_ENTERPRISE_URL environment variable is set, its
build cache node will be used as a source of cached output. If both
GRADLE_ENTERPRISE_CACHE_USERNAME and GRADLE_ENTERPRISE_CACHE_PASSWORD
are also set, task output produced by the build will be pushed to the
build cache node for use by subsequent builds.
Closes gh-23883
Previously, when a project's jar was an input into a test task, a
cache hit required the current build to be using the same JDK as the
one that created the cache entry. This was due to the Created-By
entry in the jar's manifest which will vary if JDKs with different
values for the java.version and java.specification.vendor version are
used.
This commit configures normalization of the runtime classpath to ignore
META-INF/MANIFEST.MF, thereby allowing a cache hit when the tests were
previously run on a different JDK than the one being used now. Typically
this is a different update release being used on a CI agent and a
developer's machine. This change will therefore improve the likelihood
of a cache hit once remote caching has been enabled.
Closes gh-23872
Update `AnnotationTypeMappings` so that a custom `RepeatableContainers`
instances can be used. Prior to this commit, only standard repeatables
were used when reading the annotations. This works in most situations,
but causes regressions for some `AnnotationUtils` methods.
Fixed gh-23856
Prior to this commit, several of the methods in XpathRequestMatchers
declared unused type parameters (e.g., <T>). This was obviously the
result of copying an existing method that actually needs the type
parameter for proper casting.
For example, the following ...
public <T> RequestMatcher exists() {
// ...
}
... should actually be declared without <T>, since T is not used in the
implementation or in the return type:
public RequestMatcher exists() {
// ...
}
This commit removes all unused type parameter declarations in
XpathRequestMatchers.
Side Effects:
Now that we have removed the unused type parameter declarations, users
will see the following side effects if they had previously declared a
type argument when invoking such methods.
- Java: an "Unused type arguments for the non generic method ..."
warning will be generated by the compiler, but the code will continue
to work unmodified.
- Kotlin: a "Type inference failed: Not enough information to infer
parameter T in fun ..." compiler error will be raised, causing the
code to no longer compile (see
https://youtrack.jetbrains.com/issue/KT-5464). Removal of the type
argument declaration will allow the code to work correctly again.
Closes gh-23860
Prior to this commit, several of the ResultMatcher methods used in
MockMvc declared unused type parameters (e.g., <T>). This was obviously
the result of copying an existing method that actually needs the type
parameter for proper casting.
For example, the following in RequestResultMatchers ...
public <T> ResultMatcher attribute(String name, Object expectedValue) {
// ...
}
... should actually be declared without <T>, since T is not used in the
implementation or in the return type:
public ResultMatcher attribute(String name, Object expectedValue) {
// ...
}
This commit removes all unused type parameter declarations in MockMvc
result matchers.
Side Effects:
Now that we have removed the unused type parameter declarations, users
will see the following side effects if they had previously declared a
type argument when invoking such methods.
- Java: an "Unused type arguments for the non generic method ..."
warning will be generated by the compiler, but the code will continue
to work unmodified.
- Kotlin: a "Type inference failed: Not enough information to infer
parameter T in fun ..." compiler error will be raised, causing the
code to no longer compile (see
https://youtrack.jetbrains.com/issue/KT-5464). Removal of the type
argument declaration will allow the code to work correctly again.
Closes gh-23858
The new sessionAttributeDoesNotExist() method introduced in commit
e73344fc71 declares an unused type
parameter <T>.
This commit removes that unused type parameter from the method
signature.
See gh-23756
Analogous to the attributeDoesNotExist() method in ModelResultMatchers,
this commit introduces a new sessionAttributeDoesNotExist() method in
RequestResultMatchers which asserts that the given attributes are null
in the HttpSession.
Closes gh-23756
Update `TypeMappedAnnotation` mirror resolution logic so that mapped
annotation values are also considered. Prior to this commit, mirrors
in more complex meta-annotation scenarios would not resolve correctly.
Specifically, given the following:
@interface TestAliased {
@AliasFor(attribute = "qualifier")
String value() default "";
@AliasFor(attribute = "value")
String qualifier() default "";
}
@TestAliased
@interface TestMetaAliased {
@AliasFor(annotation = Aliased.class, attribute = "value")
String value() default "";
}
@TestMetaAliased("test")
@interface TestComposed {
}
A merged `@TestAliased` annotation obtained from a `@TestComposed`
root annotation would return a `value` and `qualifier` of "".
This was because the "value" and "qualifier" mirrors needed to be
resolved against the `@TestMetaAliased` meta-annotation. They cannot be
resolved against the declared `@TestComposed` annotation because it
does not have any attributes. Our previous tests only covered a single
depth scenario where `@TestMetaAliased` was used directly on the
annotated element.
Closes gh-23767
Co-authored-by: Sam Brannen <sbrannen@pivotal.io>
This commit is necessary in order to upgrade the Gradle wrapper, since
the recent attempt to do so ended up in a corrupted JAR file for the
Gradle wrapper.
Spring Framework 5.2 introduced an EventPublishingTestExecutionListener
in the Spring TestContext Framework. This listener is automatically
registered via the spring.factories mechanism; however, this listener is
not registered in the abstract JUnit 4 and TestNG base classes.
This commit addresses this oversight by explicitly registering the
EventPublishingTestExecutionListener in the following classes.
- AbstractJUnit4SpringContextTests
- AbstractTransactionalJUnit4SpringContextTests
- AbstractTestNGSpringContextTests
- AbstractTransactionalTestNGSpringContextTests
Closes gh-23748
This commit renames the Runnable variant to executeWithoutResult
and uses a Consumer<TransactionStatus> parameter for better
consistency with TransactionCallbackWithoutResult.
Closes gh-23724
Prior to this commit, one could not test for the absence of a specific
HTTP header in a request.
This commit adds a headerDoesNotExist() method in MockRestRequestMatchers.
Closes gh-23721
Commit 979508a7f3 removed the JUnit 4
dependency from all modules except spring-test. Unfortunately, the
@Inject TCK tests (SpringAtInjectTckTests) are still based on JUnit 3.
Thus, that commit accidentally excluded those tests from the build.
This commit includes SpringAtInjectTckTests in the build again by
introducing a test runtime dependency on the JUnit Vintage TestEngine
in spring-context.
See gh-23451
Prior to this commit, it was not readily apparent what terms and units
such as kilobyte/KB and megabyte/MB represented numerically in DataSize
and DataUnit.
This commit clarifies that such terms and units are based on binary
prefixes for data (i.e., powers of 2 instead of powers of 10).
Closes gh-23697
Prior to this commit, it was not clear from the Javadoc for
BeanPostProcess and BeanFactoryPostProcessor that such components can
be ordered by implementing Ordered or PriorityOrdered.
This commit improves the documentation for BPP and BFPP to make this
support explicit.
Closes gh-23636
Bypass server cookie and write Set-Cookie header directly for Reactor
Netty, and Servlet API which do not provide options.
For Undertow use the sameSite attribute.
Closes gh-23693
Previously, the genJaxb task's input files were compared using
absolute paths. This would result in a cache miss for two builds
with identical files contents and different root directories.
This commit updates the path sensitivity of the input to be relative
to the build's root directory, thereby allowing caching to work
irrespective of the source checkout location.
Closes gh-23704
This commit adds the following exclusions to the source of the
checkstyleNoHttp tasks for each project in the build and for buildSrc:
- bin/ directory (created by Eclipse Buildship)
- .settings directory (created by Eclipse)
- .classpath file (created by Eclipse)
- .project file (created by Eclipse)
An exclusion for the build/ directory is also configured as the
NoHttp plugin does not exclude it by default for buildSrc.
Closes gh-23702
When built in an environment where many Gradle build workers are
available, :spring-webflux:test is regularly the only task running at
the end of the build. Therefore, the build's overall execution time
can be reduced by running its tests in parallel, spreading the tests'
execution across the available workers. The configured number of forks
is a maximum with Gradle reducing this as necessary for environments
with low numbers of cores where multiple workers will not improve
build performance.
Closes gh-23701
RSocket is still in its RC phase, but those artifacts are published on
maven central. This dependency is currently still depending on a
milestone dependency for Reactor adn this is causing issues with our
build.
This commits adds back the milestone repository until the RSocket POMs
and BOMs are fixed. Once fixed, the Framework build should use the
RSocket BOM for managing RSocket dependencies.
See gh-23698
The parallel forks configuration of Test tasks can have a big impact
on their execution time. This commit updates the build can
configuration to capture each Test task's maxParallelForks
configuration as custom values in the build scan. This will make this
data available when comparing scans which will be useful as we
experiment with different parallel fork settings to reduce the
build's overall execution time.
Closes gh-23691
Prior to this commit, the parameterized DataBufferFactory was never
actually used when setting up the WebClient for each test. This was due
to an oversight when migrating from JUnit 4 to JUnit Jupiter.
See: https://github.com/reactor/reactor-netty/issues/860
This commit fixes this by converting the existing @BeforeEach method to
a local setup method that is invoked from each
@ParameterizedDataBufferAllocatingTest method.
In addition, in order to avoid the 2 second "quiet period" that is
incurred when destroying the ReactorResourceFactory, this commit moves
the setup and destruction of the ReactorResourceFactory to new
@BeforeAll and @AfterAll methods.
The test instance lifecycle has also been switched to PER_CLASS to avoid
static state in the test class.
If an error looks like a "disconnected client" but the response is not
yet committed then it can't be an I/O error from writing to the server
response. It is most likely as a result of a remote call as part of
request handling.
Not setting the response to 500 in this case results in a 200 response
status despite the error. Even if it was an I/O error from the server
response, setting the status won't impact a failed response.
Closes gh-23319
Prior to this change, the Gradle API Diff task was failing due to a
missing class (a Guava class) during processing. This might be a
dependency that was previously brought by some other dependency.
This commit adds that dependency as a workaround, and improves the
Gradle API Diff task to only select relevant projects when running the
task (projects using the Java Plugin and the Maven Publish Plugin).
Take a slice of the metadata if not using composite metadata to allow
reading it multiple times. For composite metadata this is not an isuse
as it is ensured by the underlying RSocket Java API.
TransactionOperator.as(Mono) now no longer short-cuts via a Flux.next() but provides an implementation via Mono.usingWhen(…).
The short-cut previously issued a cancellation signal to the transactional Mono causing the transaction cleanup to happen without a handle for synchronization.
Using Mono.usingWhen(…) initiates transaction cleanup when the Mono completes eliminating the need for cancellation of the transactional Publisher.
This change does not fully fix gh-23304 but it softens its impact because TransactionalOperator.transactional(Mono) avoids cancellation.
This commit reverts b2704e1db6 and
configures the ReactorResourceFactory not to use global resources,
thereby allowing all tests in WebClientDataBufferAllocatingTests to
execute within approximately 2 seconds again on Mac OS.
Prior to this commit, the name of the Thread registered via
ConfigurableApplicationContext#registerShutdownHook() was the generic,
default thread name ("Thread-#"). That made it difficult to discern
which executing thread was the Spring ApplicationContext shutdown hook.
This commit improves diagnostics by setting the thread name of the
ApplicationContext shutdown hook to "SpringContextShutdownHook".
Closes gh-23670
When index == arrayLength, the array index is also out of bounds.
For this scenario, a SpelEvaluationException should be thrown instead
of ArrayIndexOutOfBoundsException.
Closes gh-23658
While resolving the regression raised in gh-23571, it came to our
attention that not all of our ClassFilter and MethodMatcher
implementations were properly cacheable with CGLIB generated proxies
due to missing (or improper) equals() and hashCode() implementations.
Although such deficiencies may not manifest themselves as bugs in Core
Spring's default arrangements, these might cause issues in custom
arrangements in user applications.
This commit addresses this by ensuring that ClassFilter and
MethodMatcher implementations properly implement equals() and
hashCode(). In addition, missing toString() implementations have been
added to improve diagnostics for logging and debugging.
Closes gh-23659
This commit renames the `metadataExtractors` method to something that is
closer to the actual intent: addming new metadata extractors against the
registry given as a parameter of the `Consumer`.
The method is renamed to `metadataExtractorRegistry`.
This commit makes sure we narrow down dependencies of the Spring
Framework to only Maven central. Optional dependencies that are not
available on Maven Central are now served from a more specific
repository (`libs-spring-framework-build`).
Closes gh-23124
Prior to this commit, Spring Framework would use `Schedulers.elastic()`
in places where we needed to process blocking tasks in a reactive
environment.
With reactor/reactor-core#1804, a new `Schedulers.boundedElastic()`
scheduler is available and achieves the same goal with added security;
it guarantees that resources are bounded.
This commit uses that new scheduler in the standard websocket client,
since the underlying API is blocking for the connection phase and we
need to schedule that off a web server thread.
Closes gh-23661
See gh-23665
This commit makes it possible to send requests without
requiring to call data(Mono.empty()). It introduces a
dedicated MetadataSpec interface and merge ResponseSpec
into RequestSpec for more flexibility.
Closes gh-23649
It seems that publishing a Gradle platform as a Maven POM writes all
dependencies with their scope information by default.
We don't want that when publishing the Spring Framework BOM, as it
forces the scope on projects depending on the BOM, unless they've
specified the scope when they added the dependency to their build.
Typically, developers could get spring-test as a compile dependency
without this change.
This commit removes the scope information from the published BOM.
Fixes gh-23660
Spring Framework 5.2 M1 introduced a memory leak for applications using
@Async methods. Specifically, in a large test suite with multiple
ApplicationContexts that were closed (e.g., via @DirtiesContext,
@MockBean, or context cache eviction), the JVM process could run out of
memory.
Underlying cause: Due to a missing equals() implementation in Spring's
new AnnotationCandidateClassFilter, CGLIB's static cache of generated
classes indirectly retained references to BeanFactory instances for the
closed ApplicationContexts for the duration of the test suite.
This commit fixes this regression by introducing a proper equals()
implementation in AnnotationCandidateClassFilter. This commit also
introduces corresponding hashCode() and toString() implementations.
Closes gh-23571
Prior to this commit, concurrent invocations of
DefaultListableBeanFactory.removeBeanDefinition() could result in a
NullPointerException.
This commit fixes this by adding an appropriate not-null check in
resetBeanDefinition().
Closes gh-23542
Prior to this commit, customizing the extraction of RSocket metadata
from frames would require developers to override the default
`MetadataExtractor` while configuring `RSocketStrategies`.
This touches on many infrastructure parts, whereas the goal is just to
configure an extra metadata entry extractor using already configured
codecs.
This commit adds a way to register metadata entry extractors on the
`RSocketStrategies` builder with a `Consumer`-based API.
Closes gh-23645
This commit removes the duplicated CRON_DISABLED constant value from
@Scheuled and simply refers to the ScheduledTaskRegistrar.CRON_DISABLED
constant.
This avoids a potential package cycle by ensuring that the `annotation`
package depends on the `config` package but not the other way around.
See gh-23568
This commit makes sure that DefaultResourceLoader consistently use
getProtocolResolvers() to access additional protocol resolvers. This
allows subclasses to define how the list is provided.
Closes gh-23564
Previously, tests in ConcurrentWebSocketSessionDecoratorTests that use
the BlockingSession would fail intermittently. This appears to have
been due to a race condition in sendBlockingMessage where the call
to getSentMessageLatch() that stores a latch in nextMessageLatch on
the main thread may happen after the call to sendMessage that counts
down the latch if it is non-null occurs on the executor's thread.
This commit updates sendBlockingMessage to call getSentMessageLatch()
(and therefore store the latch) before it sumbmits the task to the
executor. This ensures that the latch will be available when the
exeuctor's thread attempts to retrieve and decrement it.
BlockingSession's AtomicReference fields have also been made final to
eliminate the possibility of any visibility problems across threads.
Closes gh-23642
Allow `ImportBeanDefinitionRegistrar`, `ImportSelector`,
`DeferredImportSelector.Group` and `TypeFilter` to use constructor
parameters as an alternative to `*Aware` callbacks.
In order to remain backwards compatible, injection only occurs
when there is a single constructor with one or more parameters.
The following parameter types are supported:
* `Environment`
* `BeanFactory`
* `ClassLoader`
* `ResourceLoader`
In order to keep the algorithm simple, subclass parameter types are
not supported. For example, you cannot use `ConfigurableEnvironment`
instead of `Environment`.
Closes gh-23637
Add `ClientHttpRequestInitializer` interface that can be used with any
`HttpAccessor` to initialize each `ClientHttpRequest` before it's used.
This provides a useful alternative to `ClientHttpRequestInterceptor`
when users need to configure things like `HttpHeaders`.
Closes gh-22002
Prior to this commit, support was provided for disabling cron jobs
configured with an explicit "-" cron expression. However, the "-"
expression was only supported when supplied via the @Scheduled
annotation.
This commit adds support for disabling cron jobs configured with the
"-" cron expression when a cron job is registered via the
addCronTask(Runnable, String) method in the ScheduledTaskRegistrar
supplied to a SchedulingConfigurer.
Closes gh-23568
On a Servlet container a completion notification may come at any time
even in the UNSUBSCRIBED state, i.e. before the write Publisher has
called onSubscribe.
See: gh-23553
As a follow-up of gh-22915, the purpose of this commit is to improve
Coroutines programmatic transaction API to make it more consistent with
the Java one and more idiomatic.
For suspending functions, this commit changes the
TransactionalOperator.transactional extension with a suspending lambda
parameter to a TransactionalOperator.executeAndAwait one which is
conceptually closer to TransactionalOperator.execute Java API so more
consistent.
For Flow, the TransactionalOperator.transactional extension is correct
but would be more idiomatic as a Flow extension.
This commit also adds code samples to the reference documentation.
Closes gh-23627
Prior to this commit, the copyConfigurationFrom(ConfigurableBeanFactory)
method in DefaultListableBeanFactory cloned its own AutowireCandidateResolver
type instead of the resolver type from the supplied ConfigurableBeanFactory.
This commit fixes that by cloning the resolver type from the supplied
ConfigurableBeanFactory.
Closes gh-23569
Previously, some tests in spring-context wrote a file named jmx.log
into spring-context/. This led to the file being included in the
sources of the Checkstyle NoHTTP Gradle task, breaking that task's
UP-TO-DATE checks and causing it to execute unnecessarily.
This commit updates the tests to write the jmx.log file beneath
spring-context/build/ so that it is not included in the sources of the
Checkstyle NoHTTP task.
Closes gh-23623
Prior to this commit, a lot of work had been done to prevent improper
use of testing Framework APIs throughout the codebase; however, there
were still some loopholes.
This commit addresses these loopholes by introducing additional
Checkstyle rules (and modifying existing rules) to prevent improper use
of testing framework APIs in production code as well as in test code.
- Checkstyle rules for banned imports have been refactored into
multiple rules specific to JUnit 3, JUnit 4, JUnit Jupiter, and
TestNG.
- Accidental usage of org.junit.Assume has been switched to
org.junit.jupiter.api.Assumptions.
- All test classes now reside under org.springframework packages.
- All test classes (including abstract test classes) now conform to the
`*Tests` naming convention.
- As an added bonus, tests in the renamed
ScenariosForSpringSecurityExpressionTests are now included in the
build.
- Dead JUnit 4 parameterized code has been removed from
DefaultServerWebExchangeCheckNotModifiedTests.
Closes gh-22962
Previously, all tasks in the build were run sequentially. This
commit updates Gradle's properties to build them in parallel where
possible. When using the daemon (recommended) its default max heap is
not sufficient for the demands on a parallel build, therefore this
commit also increases the daemon's max heap.
See gh-23620
This commit renames Spr3896SuiteTests to comply with our naming
convention for test classes that should be executed via the Gradle
build.
The effect of this commit is that test classes included in that "suite"
are no longer executed twice in the build. Consequently, Gradle and
Bamboo will now report the same number of executed tests for the
spring-test project.
Previously, changing modules (snapshots) and dynamic versions were
cached for Gradle's default period of 24 hours and
--refresh-dependencies was used to pick up the latest artifacts. This
approach has a notable downside. --refresh-dependencies causes all
dependencies to be refreshed, irrespective of whether they are
expected to change. At a minimum, this results in a HEAD request for
every dependency in the build. Running an up-to-date build without
--refresh-dependencies takes in the region of 6 seconds:
$ ./gradlew build
BUILD SUCCESSFUL in 6s
203 actionable tasks: 203 up-to-date
The same build with --refresh-dependencies takes almost ten times as
long:
$ ./gradlew build --refresh-dependencies
BUILD SUCCESSFUL in 58s
203 actionable tasks: 203 up-to-date
This commit replaces the manual usage of --refresh-dependencies on
the command line with a 0 second caching period for changing modules
and dynamic versions. This should remove the need to use
--refresh-dependencies both locally and on CI, saving almost 1 minute
per full build.
Prior to this commit, Spring failed to determine that an XML config file
was DTD-based if the DTD declaration was followed by a comment.
This commit fixes this by modifying the consumeCommentTokens(String)
algorithm in XmlValidationModeDetector so that both leading and trailing
comments are properly consumed without losing any XML content.
Closes gh-23605
Since it does not appear that JUnit 4.13 will be released before Spring
Framework 5.2 GA, I am reverting back to JUnit 4.12 for the time being.
See gh-22894
When exposed as an environment variable Bamboo's bamboo.resultsUrl
is mapped to bamboo_resultsUrl. This commit updates the build scan
user data script to look for the latter rather than the former.
Closes gh-23597
When exposed as an environment variable Bamboo's bamboo.resultsUrl
is mapped to bamboo_resultsUrl. This commit updates the build scan
user data script to look for the latter rather than the former.
When exposed as an environment variable Bamboo's bamboo.resultsUrl
is mapped to bamboo_resultsUrl. This commit updates the build scan
user data script to look for the latter rather than the former.
This commit adds opt-in build scan integration with Gradle Enterprise.
When the GRADLE_ENTERPRISE_URL environment variable is set on a
developer's machine or on CI, a build scan will be automatically
uploaded to Gradle Enterprise at the end of the build.
This initial integration will establish a baseline for Spring
Framework builds. Once that baseline has been established we can use
the build scans to identify ways in which the build can be optimized
and updated to make use of Gradle's build caching which should reduce
build times, significantly so for changes that only affect tasks near
the leaf nodes of the task graph.
Prior to this commit, the isSimpleProperty() and isSimpleValueType()
methods in BeanUtils treated void and Void as simple types; however,
doing so does not make sense in this context, since void implies the
lack of a property or value.
This commit addresses this by explicitly excluding void and Void in the
logic in isSimpleValueType().
This commit also simplifies the implementation of
ViewResolutionResultHandler.supports(HandlerResult) to take advantage
of this change.
Closes gh-23573
MergedAnnotations provides 'from' variants with RepeatableContainers but without AnnotationFilter argument now, avoiding the need to refer to AnnotationFilter.PLAIN as a default at call sites.
The org.reactivestreams has 13 instead of 4 classes in 1.0.3 with the
addition of Java 9 Flow adapters. This commit switches to using a
different package reactor.util.annotation, also with a small number of
classes, for this test.
This commit reverts all artifactory configuration changes in this
branch. A new build plan has been created for the master branch which is
tailored for the latest Gradle changes made on that branch.
This commit adds a missing dependency from the artifactoryPublish task
to the "install" task as POMs are currently missing from the published
artifacts and they are generated with the "install" task here.
This commit adds Coroutines extensions for
TransactionalOperator.transactional that accept suspending lambda or
Kotlin Flow parameters.
@Transactional on suspending functions is not supported yet, gh-23575
has been created for that purpose.
Closes gh-22915
Prior to this commit, tests in spring-web and spring-webflux were no
longer executed due to the removal of the Hamcrest dependency in
commit bb03cdf5d0.
This commit enables the publishing of Gradle metadata with Spring
Framework artifacts. This feature will be enabled by default with Gradle
6.0, so Spring Framework will consistently push this information in the
5.2.x generation.
Fixes gh-23503
Prior to this commit, ClassUtils.isPrimitiveOrWrapper() and
ClassUtils.isPrimitiveWrapper() did not return true for Void.class.
However, ClassUtils.isPrimitiveOrWrapper() did return true for
void.class. This lacking symmetry is inconsistent and can lead to bugs
in reflective code.
See: https://github.com/spring-projects/spring-data-r2dbc/issues/159
This commit addresses this by adding an entry for Void.class -> void.class
in the internal primitiveWrapperTypeMap in ClassUtils.
Closes gh-23572
Prior to this commit, the Spring Framework build would partially use the
dependency management plugin to import and enforce BOMs.
This commit applies the dependency management plugin to all Java
projects and regroups all version management declaration in the root
`build.gradle` file (versions and exclusions).
Some versions are overridden in specific modules for
backwards-compatibility reasons or extended support.
This commit also adds the Gradle versions plugin that checks for
dependency upgrades in artifact repositories and produces a report; you
can use the following:
./gradlew dependencyUpdates
This commit makes sure that reading is enabled after the current
signal has been processed, not while is is being processed. The bug
was only apparent while using the JettyClientHttpConnector, which
requests new elements continuously, even after the end of the
stream has been signalled.
This allows encoding of metadata values externally via some
existing API for encoding RSocket metadata, rather than relying on
registered Encoders.
Also remove explicit checks for DataBuffer since those are supported
through the DataBufferEncoder (registered by default).
See gh-23513
Prior to this commit, the entry set of read-only HttpHeaders lost the
original headers' ordering.
The changes in commit ce7278aaf4 introduced a regression in the read-only
HttpHeaders support. Specifically, the implementation of entrySet() in
the internal ReadOnlyHttpHeaders class converted the original entry set
to an immutable, non-ordered set of immutable entries.
This commit fixes this issue by converting the original entry set to an
immutable, ordered set of immutable entries.
Closes gh-23551
Prior to this commit, it was impossible to include a placeholder (i.e.,
${placeholder.name}) in a Properties file location configured via
@TestPropertySource if the placeholder was immediately followed by a
relative path (i.e., "../"). This was due to the fact that the location
was always cleaned using StringUtils.cleanPath(), which removed the
placeholder and the relative path syntax.
This commit fixes this by preserving all placeholders in
@TestPropertySource locations by simply not cleaning the locations if
they contain placeholders.
Closes gh-23544
This commit ensures that locations to resources configured via
@ContextConfiguration & @TestPropertySource are consistently cleaned
using StringUtils.clean().
See gh-23544
This commit introduces a collection of @Nested integration tests that
verify proper support for @TestPropertySource with explicit properties
files declared with absolute paths, relative paths, and placeholders in
the classpath and in the file system.
See gh-23544
This commit prepends "[{index}] " to all custom display names
configured via @ParameterizedTest.
This provides better diagnostics between the "technical names" reported
on the CI server vs. the "display names" reported within a developer's
IDE.
See gh-23451
This commit introduces a test that verifies that
PathMatchingResourcePatternResolver can find files in the filesystem
that contain hashtags (#) in their names.
See gh-23532
This commit makes sure we narrow down dependencies of the Spring
Framework to only Maven central. Optional dependencies that are not
available on Maven Central are now served from a more specific
repository (`ext-release-local`).
Closes gh-23124
Since gh-23282, our CI does not apply automatically the Artifactory
Gradle plugin during our build and we're now applying it "manually".
This commit backports this change since the build configuration is
shared between branches.
See gh-23282
Prior to this commit, there was no way to replace the Set-Cookie header
via MockHttpServletResponse. Specifically, an invocation of setHeader()
for the Set-Cookie header resulted in an additional Set-Cookie header
instead of replacing the existing one, which is in violation of the
contract for javax.servlet.http.HttpServletResponse.setHeader(...).
This commit refactors the internals of MockHttpServletResponse to ensure
that an existing Set-Cookie header is overwritten when set via an
invocation of setHeader(). This commit also verifies the expected
behavior for addHeader() and addCookie() with regard to multiple cookies.
Closes gh-23512
For public use, these constants aren't ideally exposed through an SPI
like MetadataExtractor, and there isn't any other obvious place either.
In practice the only public API where these can be passed in is
RSocketRequester and RSocketMessageHandler both of which already
default to composite metadata anyway, leaving only the routing MimeType
to be used potentially but much less likely.
Due to existence of similar constants in the RSocket itself, i.e.
WellKnownMimeType, we can get by internally too without declaring
MimeType constants from a central place.
This commit polishes tests in spring-aop by using
OrderComparator.sort() and lambda expressions instead of anonymous
classes where feasible.
Closes gh-23458
Prior to this commit, the AutowiredArgumentMarker type was repeatedly
instantiated in ConstructorResolver.
This commit replaces the AutowiredArgumentMarker type with a simple
Object instance.
Closes gh-23469
Prior to this commit, the invokeMethod() utility method in
ReflectionTestUtils only supported instance methods.
This commit brings the invokeMethod() support on par with the getField()
support by supporting the invocation of static methods via two new
invokeMethod() variants.
Closes gh-23504
Due to a bug (or "unintentional feature") in JUnit 4, overridden test
and lifecycle methods not annotated with @Test, @Before, @After, etc.
are still executed as test methods and lifecycle methods; however,
JUnit Jupiter does not support that. Thus, prior to this commit, some
overridden test and lifecycle methods were no longer executed after the
migration from JUnit 4 to JUnit Jupiter.
This commit addresses this issue for such known use cases, but there
are likely other such use cases within Spring's test suite.
See gh-23451
This commit ensures that file streams are properly closed in tests.
This seems to cause issues on Windows as the OS cannot delete temp
folders.
This is similar to spring-io/initializr#862
See gh-23507
This commit ensures that Gradle publications are using resolved
dependency versions for Maven publications (i.e. POMs). This is useful
since we're using the Spring dependency management plugin and we can't
rely on declared dependency versions only.
See gh-23282
Instead of relying on the CI server to apply and configure this plugin,
this commit does it directly in the Spring Framework build.
This allows us to take full control over which projects are published
and how.
See gh-23282
This commit switches to the default publication name considered by the
artifactory plugin when it comes to publishing artifacts to the
artifactory repository.
See gh-23282
Prior to this commit, the build would use a custom task to create a BOM
and manually include/exclude/customize dependencies. It would also use
the "maven" plugin to customize the POM before publication.
This commit now uses a Gradle Java Platform for publishing the Spring
Framework BOM. We're also now using the "maven-publish" plugin to
prepare and customize publications.
This commit also tells the artifactory plugin (which is currently
applied only on the CI) not to publish internal modules.
See gh-23282
This commit configures the Gradle Download plugin that's used a build
step when generating the reference documentation. Here we're making sure
that the task is caching and reusing the resource if it's been
downloaded already.
See gh-23282
Prior to this commit, the Spring Framework build would mix proper
framework modules (spring-* modules published to maven central) and
internal modules such as:
* "spring-framework-bom" (which publishes the Framework BOM with all
modules)
* "spring-core-coroutines" which is an internal modules for Kotlin
compilation only
This commit renames these modules so that they don't start with
"spring-*"; we're also moving the "kotlin-coroutines" module under
"spring-core", since it's merged in the resulting JAR.
See gh-23282
The use of LinkedCaseInsensitiveMap, going back to 3.0, makes it
unnecessary to iterate over keys which can cause
ConcurrentModificationException.
Closes gh-23460
Previously DefaultWebClientBuilder always defaulted the ClientHttpConnector
with ReactorClientHttpConnector. This worked fine if reactor was used.
However, it would break if the user was trying to leverage Jetty.
This commit defaults to use Reactory Netty HttpClient if it is present. If
it is not present it then Jetty's HttpClient is used if present.
Closes gh-23491
Prior to this commit, the reference documentation build with asciidoctor
would get the common "spring-docs-resources" as a dependency and then
use it when generating the docs.
As seen in #23124, this can cause problems since we'd like to
consistently resolve our dependencies. In this case, the
"spring-doc-resources" archive is not published on maven central since
it's not officially supported by the Spring team as an open source
project.
This commit updates the reference documentation build to get this
archive as a simple download task and avoid resolving it as a
dependency.
See gh-23282
This commit ensures that the spring-framework-bom project is ignored
from the global configuration block. If not, many conventions and
dependencies are added to it and add noise to the published BOM.
See gh-23282
This commit reorganizes tasks and scripts in the build to only apply
them where they're needed. We're considering here 3 "types" of projects
in our build:
* the root project, handling documentation, publishing, etc
* framework modules (a project that's published as a spring artifact)
* internal modules, such as the BOM, our coroutines support and our
integration-tests
With this change, we're strealining the project configuration for all
spring modules and only applying plugins when needed (typically our
kotlin support).
See gh-23282
Due to a bug (or "unintentional feature") in JUnit 4, overridden test
methods not annotated with @Test are still executed as test methods;
however, JUnit Jupiter does not support that. Thus, prior to this
commit, some overridden test methods in spring-core were no longer
executed after the migration from JUnit 4 to JUnit Jupiter.
This commit addresses this issue for such known use cases, but there
are likely other such use cases within Spring's test suite.
See gh-23451
The recently added body(Object) variant can be confused easily with
body(Publisher, Class) forgetting to provide the element type and
only running into the IllegalArgumentException at runtime.
See gh-23212
This commit moves the dependency management and test source files
related to integration tests to a dedicated module.
This allows us to focus the root project on building the Spring
Framework.
See gh-23282
This commit removes JDiff from the Spring Framework build and instead,
adds a Gradle plugin that configure JApiCmp tasks on the framework
modules.
Fixes gh-22942
See gh-23282
Add `SpringJUnit5` checkstyle rule to ensure that JUnit 4 annotations
aren't accidentally used in new tests.
The "must not be public" rule has been suppressed since there are
quite a few tests that extend base tests from other packages.
This commit migrates the spring-test test suite from JUnit 4 to JUnit
Jupiter where applicable.
Tests specific to our JUnit 4 and TestNG support remain written using
those frameworks. In addition, some tests are still written in JUnit 4
if they extend a test class that should not be migrated to JUnit
Jupiter.
See gh-23451
This commit removes the JUnit 4 dependency from all modules except
spring-test which provides explicit JUnit 4 support.
This commit also includes the following.
- migration from JUnit 4 assertions to JUnit Jupiter assertions in all
Kotlin tests
- migration from JUnit 4 assumptions in Spring's TestGroup support to
JUnit Jupiter assumptions, based on org.opentest4j.TestAbortedException
- introduction of a new TestGroups utility class than can be used from
existing JUnit 4 tests in the spring-test module in order to perform
assumptions using JUnit 4's Assume class
See gh-23451
This commit migrates parameterized tests in spring-core using the
"composed @ParameterizedTest" approach. This approach is reused in
follow-up commits for the migration of the remaining modules.
For a concrete example, see AbstractDataBufferAllocatingTests and its
subclasses (e.g., DataBufferTests).
Specifically, AbstractDataBufferAllocatingTests declares a custom
@ParameterizedDataBufferAllocatingTest annotation that is
meta-annotated with @ParameterizedTest and
@MethodSource("org.springframework.core.io.buffer.AbstractDataBufferAllocatingTests#dataBufferFactories()").
Individual methods in concrete subclasses are then annotated with
@ParameterizedDataBufferAllocatingTest instead of @ParameterizedTest or
@Test.
The approach makes the migration from JUnit 4 to JUnit Jupiter rather
straightforward; however, there is one major downside. The arguments
for a @ParameterizedTest test method can only be accessed by the test
method itself. It is not possible to access them in an @BeforeEach
method (see https://github.com/junit-team/junit5/issues/944).
Consequently, we are forced to declare the parameters in each such
method and delegate to a custom "setup" method. Although this is a bit
cumbersome, I feel it is currently the best way to achieve fine grained
parameterized tests within our test suite without implementing a custom
TestTemplateInvocationContextProvider for each specific use case.
Once https://github.com/junit-team/junit5/issues/878 is resolved, we
should consider migrating to parameterized test classes.
See gh-23451
This first commit for this issue:
- allows JUnit Jupiter to be used for all tests
- adds a dependency on mockito-junit-jupiter
- migrates tests in spring-core to JUnit Jupiter, except parameterized
tests
The following script was developed in order to semi-automate the
migration process.
https://github.com/sbrannen/junit-converters/blob/master/junit4ToJUnitJupiter.zsh
See gh-23451
This commit removes unused parts of the Gradle build:
* Gradle wrapper customization which should not be needed in recent
versions of Gradle (or can be replaced with options in the
gradle.properties file)
* the branch strategy configuration
See gh-23282
This commit moves the compile configuration from the Gradle DSL to a
convention. This configuration is not changing often, and we're using
that opportunity to make the Java source compatibility a project
property so as to easily recent JDKs this on the command line.
See gh-23282
ClassLoaderAwareUndeclaredThrowableStrategy fails with a VerifyError on recent JDKs after the CGLIB 3.3 upgrade. The alternative is to replace it with a plain ClassLoaderAwareGeneratorStrategy (extracted from CglibSubclassingInstantiationStrategy) and custom UndeclaredThrowableException handling in CglibMethodInvocation.
See gh-23453
Prior to this commit, the Spring Framework build would be using the
propdeps Gradle plugin to introduce two new configurations to the build:
"optional" and "provided". This would also configure related conventions
for IDEs, adding those configurations to published POMs.
This commit removes the need for this plugin and creates instead a
custom plugin for an "optional" configuration. While the Eclipse IDE
support is still supported, there is no need for specific conventions
for IntelliJ IDEA anymore.
This new plugin does not introduce the "provided" scope, as
"compileOnly" and "testCompileOnly" are here for that.
Also as of this commit, optional/provided dependencies are not published
with the Spring Framework modules POMs annymore.
Generally, these dependencies do not provide actionable information to
the developers reading / tools consuming the published POMs.
Optional/Provided dependencies are **not**:
* dependencies you can add to enable some supported feature
* dependencies versions that you can use to figure out CVEs or bugs
* dependencies that might be missing in existing Spring applications
In the context of Spring Framework, optional dependencies are just
libraries are Spring is compiling against for various technical reasons.
With that in mind, we are not publishing that information anymore.
See gh-23282
This commit moves the existing "test sources" Gradle plugin from Groovy
to Java and updates the "buildSrc" build file to prepare for additional
plugins in the Spring Framework build.
The plugin itself looks, for a given Spring Framework module, at all the
project dependencies for the following scopes: "compile", "testCompile",
"api", "implementation" and "optional" (to be supported by a different
plugin).
See gh-23282
This commit introduces Kotlin code snippets, for now
in the core reference documentation. Other sections
will follow, as well as improvements like global
language switch.
See gh-21778
This commit avoids unnecessary processing in the implementation of
postProcessBeforeInitialization() in ApplicationContextAwareProcessor
by immediately returning the supplied bean if it does not meet the
requirements for further processing.
Closes gh-23435
Prior to this commit, StopWatch used System.currentTimeMillis() to
track and report running time in milliseconds.
This commit updates the internals of StopWatch to use System.nanoTime()
instead of System.currentTimeMillis(). Consequently, running time is
now tracked and reported in nanoseconds; however, users still have the
option to retrieve running time in milliseconds or seconds.
Closes gh-23235
This commit avoids the use of the deprecated
GenericTypeResolver.resolveParameterType() method in tests in order to
avoid warnings in the Gradle build.
Since arbitrary levels of proxies do not occur, this commit replaces
the `while` loop in SerializableTypeWrapper.unwrap() with a simple
`if` statement.
Closes gh-23415
Since Java 8, putIfAbsent() is a standard method in java.util.Map. We
therefore no longer need the custom implementation that overrides the
standard implementation in HashMap.
Prior to this commit, AnnotationAttributes#assertNotException checked if
the attribute value was an instance of Exception. Although this was
typically sufficient, the scope was not always broad enough -- for
example, if AnnotationReadingVisitorUtils#convertClassValues stored a
Throwable in the map (such as a LinkageError).
This commit fixes this by checking for an instance of Throwable in
AnnotationAttributes#assertNotException.
Closes gh-23424
We now reuse interfaces for EntityManager and Query classes that
are proxied through ExtendedEntityManagerCreator and SharedEntityManagerCreator.
These caches prevent excessive object allocations through
ClassUtils.getAllInterfacesForClass(…) and
ClassUtils.getAllInterfacesForClassAsSet(…).
Deprecate all mutation methods in `MethodParameter` in favor of factory
methods that return a new instance. Existing code that previously relied
on mutation has been updated to use the replacement methods.
Closes gh-23385
Update `AbstractAutowireCapableBeanFactory.getTypeForFactoryBean` to
use fallback to `determineTargetType` if the factory bean definition
does not have a resolved class.
This is required for the case where a `@Configuration` class is picked
up via component scanning and has a bean type that has not yet been
resolved.
Closes gh-23338
Prior to this commit, the new `TYPE_HIERARCHY_AND_ENCLOSING_CLASSES`
annotation search strategy failed to find annotations on enclosing
classes if the source class was a nested class that itself had no
annotations present.
This commit fixes this by adding special logic to AnnotationsScanner's
isWithoutHierarchy() method to properly support nested classes.
Closes gh-23378
Add a `TYPE_HIERARCHY_AND_ENCLOSING_CLASSES` annotation search strategy
that can be used to search the full type hierarchy as well as any
enclosing classes.
Closes gh-23378
Update code that's often called so that zero length array results use
a single shared static constant, rather than a new instance for each
call.
Closes gh-23340
Update `getTypeForFactoryBean` detection so that a bean definition
attribute can be used to supply the result. This commit allows projects
such as Spring Data to provide the result that would be supplied by
`getObjectType` early so that we don't need to initialize the
`FactoryBean` unnecessarily.
Closes gh-23338
Update the `FactoryBean` type prediction logic (primarily in the
`DefaultListableBeanFactory`) so that generic type information is
considered when calling `getBeanNamesForType` on a non-frozen
configuration.
Calling `getBeanNamesForType` with `allowEagerInit` disabled will now
detect `FactoryBean` variants as long as generic type information is
available in either the class or the factory method return type.
Closes gh-23338
Update the logic in `AbstractBeanFactory` so that caches from merged
bean definitions remain whenever possible.
Prior to this commit, all merged bean definitions would be completely
removed after bean post processing in case a processor changed the bean
type. It's fairly unlikely these days that the bean type will actually
change, so instead we now compare a subset of the old cached properties
against the newly created definition. Only if key properties have
changed do we now discard the older cached values.
Closes gh-23336
Update `ListableBeanFactory` and `BeanFactoryUtils` to add the missing
`getBeanNamesForType` methods that accept a `ResolvableType` rather
than a `Class`.
This completes the work started in 778a01943b.
Closes gh-23335
Added support for status codes that do not occur in HttpStatus in
DefaultClientResponseBuilder and made ClientResponse::statusCode
ClientHttpResponse::getStatusCode @Nullable.
Closed gh-23366
Expecting data first and metadata second aligns better with the single
arg variant that accepts data. This is also consistent with the
RSocket API in the create methods of ByteBufPayload and DefaultPayload.
- Add onRawStatus to WebClient.ResponseSpec, allowing users to deal with
raw status codes that are not in HttpStatus.
- No longer throw an exception status codes not in HttpStatus.
Closes gh-23367
The isJavaIdentifier check is not really required, but also seems
intuitive for variables to be Java identifier-like. This commit relaxes
the constraint a bit by also allowing "-".
Closes gh-23101
Prior to this commit, the SimpleUrlHandlerMapping classes in Spring MVC
and Spring Webflux only had default constructors. This lead to the fact
that users often had to explicitly invoke setUrlMap() and setOrder() on
the newly instantiated SimpleUrlHandlerMapping.
In order to simplify the programmatic setup of a SimpleUrlHandlerMapping
in common scenarios, this commit introduces the following constructors.
- SimpleUrlHandlerMapping()
- SimpleUrlHandlerMapping(Map<String, ?> urlMap)
- SimpleUrlHandlerMapping(Map<String, ?> urlMap, int order)
Closes gh-23362
This commit introduces tests which verify that properties configured via
@TestPropertySource used as a meta-annotation override those configured
via @TestPropertySource used as a meta-meta-annotation.
See gh-23320
Prior to this commit, if multiple, directly present
`@TestPropertySource` annotations declared the same property, the
precedence ordering was top-down instead of bottom-up, in contrast to
the semantics for class hierarchies. In other words, a subsequent
`@TestPropertySource` annotation could not override a property in a
previous `@TestPropertySource` annotation.
This commit overhauls the internals of `TestPropertySourceUtils` in
order to provide proper support for property overrides within local,
directly present `@TestPropertySource` declarations.
Specifically, the `locations` and `properties` attributes from all
`@TestPropertySource` declarations that are directly present or
meta-present on a given class are now merged into a single instance of
`TestPropertySourceAttributes` internally, with assertions in place to
ensure that such "same level" `@TestPropertySource` declarations do not
configure different values for the `inheritLocations` and
`inheritProperties` flags. Effectively, all "same level"
`@TestPropertySource` declarations are treated internally as if there
were only one such annotation declared by the user.
See gh-23320
Prior to this commit, @TestPropertySource could not be declared as a
repeatable annotation. In addition, a local declaration of
@TestPropertySource would silently override a meta-present
@TestPropertySource.
This commit addresses this issue by introducing @TestPropertySources as
a container for @TestPropertySource. This commit also updates the
search and algorithms within TestPropertySourceUtils.
Closes gh-23320
Use rsocketStrategies field with mutate() to ensure consistency
with internal state.
Remove transparent initialization of decoders in MetadataExtractor
and expect them to be set to avoid unintended side effects.
Remove RSocketStrategies argument from the contract to avoid having to
pass them every time especially by application components, like an
implementation of a Spring Security matcher.
Decouple DefaultMetadataExtractor from RSocketStrategies in favor of
a decoders property and an internal DataBufferFactory, which does not
need to be the shared one as we're only wrapping ByteBufs.
Prior to this commit, the `header(String, String)` method in the
ServerHttpRequest.Builder API actually added a header value instead of
setting or overriding a header value. Since this conflicted with the
stated behavior in the Javadoc as well as the original intention of the
method, we have decided to introduce an overloaded variant
`header(String, String...)` which accepts a var-args list of header
values to set or override.
In addition, this commit deprecates the existing `header(String, String)`
method for removal in Spring Framework 5.2.
In order not to be a breaking change for custom implementations of the
builder API, this commit implements the new `header(String, String...)`
method as an interface `default` method, with the intent to remove the
default implementation in Spring Framework 5.2
closes gh-23333
Prior to this commit, the `header(String, String)` method in the
ServerHttpRequest.Builder API actually added a header value instead of
setting or overriding a header value. Since this conflicted with the
stated behavior in the Javadoc as well as the original intention of the
method, we have decided to introduce an overloaded variant
`header(String, String...)` which accepts a var-args list of header
values to set or override.
In addition, this commit deprecates the existing `header(String, String)`
method for removal in Spring Framework 5.2.
In order not to be a breaking change for custom implementations of the
builder API, this commit implements the new `header(String, String...)`
method as an interface `default` method, with the intent to remove the
default implementation in Spring Framework 5.2
closes gh-23333
If there is more than one non-basic codec (e.g. CBOR and JSON)
RSocketRequester.Builder takes the mime type of the first one rather
than giving up. It is a valid scenario (JSON for server responding to
browser, and CBOR for client talking to server) and it is the default
situation in Boot, and after all the point here is to pick some default
as best as we can with the worst possible outcome being a server
refusing the connection if it doesn't support the mime type. Beyond
that applications can set the dataMimeType on the builder explicitly.
To match that change this commit also ensures RSocketMessageHandler
rejects proactively data mime types it does not support at the point
of accepting a connection.
This commit ensures getRSocketStrategies() now reflects the state of
corresponding RSocketMessageHandler properties even if those change
after a call to setRSocketStrategies.
RSocketMessageHandler has default Encoder/Decoder initializations
consistent with the recent changes to RSocketStrategies.
Now that responder RSocketStrategies also exposes responder strategies,
AnnotationClientResponderConfigurer is reduced and no longer needs to
be public. This commit folds it into RSocketMessageHandler as a nested
class and exposes it as a ClientRSocketFactoryConfigurer through a
static method that accepts the handlers to use.
Effectively a shortcut for creating RSocketMessageHandler, giving it
RSocketStrategies, calling afterPropertiesSet, and then the instance
createResponder.
See gh-23314
Now that RSocketStrategies has default settings it makes sense to have
a create() shortcut vs builder().build().
This commit also updates tests to take advantage of improvements in this
and the previous two commits.
See gh-23314
RouteMatcher and MetadataExtractor can now be configured on and
accessed through RSocketStrategies. This simplifies configuration for
client and server responders.
See gh-23314
1. RSocketStrategies hooks in the basic codecs from spring-core by
default. Now that we have support for composite metadata, it makes
sense to have multiple codecs available.
2. RSocketStrategies is pre-configured with NettyDataBufferFactory.
3. DefaultRSocketRequesterBuilder configures RSocket with a frame
decoder that matches the DataBufferFactory choice, i.e. ensuring
consistency of zero copy vs default (copy) choice.
4. DefaultRSocketRequesterBuilder now tries to find a single non-basic
decoder to select a default data MimeType (e.g. CBOR), or otherwise
fall back on the first default decoder (e.g. String).
See gh-23314
gh-23289 introduced support for multiple single-line comment prefixes
for ScriptUtils, ResourceDatabasePopulator, and EmbeddedDatabaseBuilder.
This commit adds the same support for @SqlConfig in the TestContext
Framework. Specifically, @SqlConfig has a new `commentPrefixes`
attribute for setting multiple single-line comment prefixes.
Closes gh-23331
To make the switching of separators complete, it is also important to
know whether the decoding of path segment values and the parsing of
path param should be done as those are applied transparently.
This commit replaces the recently added separator argument to
PathContainer.parsePath with an Options type with two predefined
constants. One for HTTP URLs with automatic decoding and parsing of
path params, and another for "." separated message routes without
decoding except for encoded sequences of the separator itself.
See gh-23310
Commit eec183ef28 configured the
Artifactory Gradle task in the Default Job of the Bamboo build plan for
the Spring Framework (SPR-PUB) to use the following Gradle-friendly test
results directory pattern: `**/build/test-results/**/*.xml`.
That change made the existing custom configuration of the test results
directory in the common Gradle `test` task obsolete.
Prior to this commit, the standard Gradle `test` task was configured to
execute all JUnit tests and had a dependency on the `testNG` task. In
addition, the `aggregateTestReports` task depended on the results of
the `test` and `testNG` tasks as input. Consequently, a subsequent
execution of the `aggregateTestReports` task would not be considered
UP-TO-DATE since the JUnit and TestNG results were both written to the
same "test" reports folder.
This commit introduces a new `junit` test task that allows JUnit and
TestNG test output to be completely independent. The standard `test`
task now depends on `junit` and `testNG` but does not execute any tests
itself, and the `aggregateTestReports` task now depends on the
individual `junit` and `testNG` results instead of on the mixed `test`
results.
See also: eec183ef28
Prior to these commits method-level @Sql declarations always overrode
class-level @Sql declarations, which required developers to redeclare
class-level @Sql declarations on test methods (e.g., via
copy-and-paste) in order to combine them with method-level @Sql
declarations.
These commits provide developers the ability to optionally merge
class-level and method-level @Sql declarations via a new @SqlMergeMode
annotation that can be applied at the class level or method level, with
method-level declarations of @SqlMergeMode overriding class-level
declarations. For example, @SqlMergeMode(MERGE) switches from the
default OVERRIDE behavior to merging behavior, with class-level SQL
scripts and statements executed before method-level SQL scripts and
statements.
Closes gh-1835
This commit upgrades Coroutines support to kotlinx.coroutines
1.3.0-RC, leverages the new Coroutines BOM and refine Coroutines
detection to avoid false positives.
Only Coroutines to Mono context interoperability is supported
for now.
CLoses gh-23326
This covers ApplicationListener generics in factory method return types in particular but also allows for programmatic setTargetType hints.
Closes gh-23178
Fix `isAssignable` for `ResolvableType.forRawClass` so that it can be
used with types backed by a `TypeVarible`. Prior to this commit the
rawClass value was used, which wouldn't always work.
Closes gh-23321
Prior to this commit, AbstractAutowireCapableBeanFactory's
invokeCustomInitMethod() method invoked
ClassUtils.getInterfaceMethodIfPossible() even if the security manager
was not being used.
This commit ensures that getInterfaceMethodIfPossible() is only invoked
if the security manager is used.
Closes gh-23323
Replace docs on using MultipartBodyBuilder for the RestTemplate with
examples that show MultiValueMap. Originally the idea was to make
MultipartBodyBuilder accessible to the RestTemplate too, but with
support for async parts that's no longer a good fit.
Closes gh-23295
This commit copies the toEntity and toEntityList methods from
ClientResponse to ResponseSpec, so that it is possible to retrieve
a ResponseEntity when using retrieve().
Closes gh-22368
The new interface supersedes ClientResponderFactory and is more general,
for any RSocketFactory customization.
DefaultClientResponderFactory implements the new interface and is
renamed to AnnotationClientResponderConfigurer.
See gh-23170
Simplify the creation of MetadataExtractor by not requiring
RSocketStrategies up front. The strategies are already configured in higher
level places like RSocketMessageHandler that invoke the MetadataExtractor.
The strategies are now passed in as an argument to the extract method.
@CacheEvict.beforeInvocation suggests immediate execution even in case of transactional caches. The cache interceptor delegates to the new evictIfPresent/invalidate operations now which imply immediate execution semantics (and also provide an indication for whether any corresponding entries where present when programmatically called).
Closes gh-23192
Prior to this commit, there was some ambiguity surrounding semantics
for @Autowired constructors and `required = true`, especially for
multiple @Autowired constructors.
This commit improves the documentation in the Javadoc for @Autowired as
well as in the reference manual.
Closes gh-23263
Prior to this commit, a null path supplied to the isPattern(), match(),
and matchStart() methods in AntPathMatcher resulted in a
NullPointerException.
This commit addresses this by treating a `null` path as a non-matching
pattern.
Closes gh-23297
Prior to this commit, the `RSocketRequester.Builder` would allow to
configure directly annotated handlers for processing server requests.
This lead to a package tangle where the `o.s.messaging.rsocket` would
use classes from `o.s.messaging.rsocket.annotation.support` package.
This commit introduces the `ClientResponderFactory` interface for
configuring a responder on the client RSocket factory. Its goal is
to be compatible with future changes with a functional variant for
RSocket handlers.
Closes gh-23170
Prior to this commit, returning an empty mono from an exception handler
registered through ResponseSpec::onStatus would result in memory leaks
(since the response was not read) and in an empty response from bodyTo*
methods of the webclient.
As of this commit, that same empty mono is now interpreted to return
the body (and not an exception), offering a way to override the default
status handlers and return a normal response for 4xx and 5xx status
codes.
This commit adds a getContentAsString(Charset fallbackCharset) method
to MockHttpServletResponse in order to make it easier to get the content
in a specific charset like UTF-8 when the response charset has not been
explicitly set (by default ISO-8859-1 is used).
JsonPathResultMatchers leverages this new feature to support UTF-8
content out of the box.
Closes gh-23219
Update `ResourceDatabasePopulator` and `ScriptUtils` so that more than
one comment prefix can be used when processing SQL scripts. This
feature is particularly useful when dealing with scripts provided by
Quartz since they often use a mix `--` and `#`.
Closes gh-23289
OncePerRequestFilter now has a doFilter method that allows separate
processing of nested ERROR dispatches. This is useful for filters
that wrap the request and response.
Closes gh-23196
This commit simplifies the build for spring-test by running JUnit 4
tests and JUnit Jupiter tests together in the standard Gradle `test`
task.
As an added bonus, the ignored tests in SpringJUnit4ConcurrencyTests
and ClassLevelDisabledSpringRuleTests are now reported in the test
results.
See gh-23286
Prior to this commit, ParallelExecutionSpringExtensionTests.TestCase
was accidentally included in the build which skewed the number of tests
in spring-test by 1000.
This commit fixes the behaviour of not triggering a transactional event
listener if no transaction is active. Previously, a transaction boundary
was all that was necessary to trigger the listener regardless of the fact
there was an active transaction.
This commit now prevents `Propagation.NOT_SUPPORTED` and
`Propagation.SUPPORTS` without an active transaction to trigger the
listener.
Closes gh-23276
This commit adds the createException() method to ClientResponse,
returning a delayed WebClientResponseException based on the status code,
headers, and body as well as the corresponding request.
Closes gh-22825
This commit refactors the internals of
LocalVariableTableParameterNameDiscoverer to use
java.lang.reflect.Executable in order to simplify the implementation.
Prior to this commit, @TestConstructor supported a boolean `autowire`
attribute which naturally limited the configuration to two states: on
or off. Since we may need to support additional autowiring modes in the
future, the use of a boolean is limiting.
This commit address this issue by introducing a new AutowireMode enum
in @TestConstructor with ALL and ANNOTATED constants. In addition, the
attribute has been renamed to `autowireMode`, and the system property
has been renamed to `spring.test.constructor.autowire.mode` for greater
clarity of purpose.
Closes gh-23224
This commit adds an engineSupplier property to ScriptTemplateConfigurer
and ScriptTemplateView in order to be able to customize the ScriptEngine
when sharedEngine is set to false.
This can be useful with Graal.js for example.
Closes gh-23258
DataBuffers::split (and underlying algorithm) should not be returning
a Flux<DataBuffer>, but rather a Flux<Flux<DataBuffer>>. In other words,
it should not join all data buffers that come before a delimiter.
Providing an implementation of a such a fully reactive split method
proved to be beyond the scope of this release, so this commit removes
the method altogether.
Due to the imminent removal of DataBufferUtils.split, this commit copies
over the buffering split algortihm from DataBufferUtils, as it is still
sutable for the StringDecoder
The DefaultMultipartMessageReader has been removed for 5.2 and will be
part of a future release. This commit switches back to the
SynchronossPartHttpMessageReader.
gh-21659
Prior to this commit, the Basic Authentication credentials were encoded for
each request in ExchangeFilterFunctions.basicAuthentication(String, String).
This commit addresses this minor performance issue by encoding the
credentials prior to the creation of the lambda expression returned by
ExchangeFilterFunctions.basicAuthentication(String, String).
Closes gh-23256
The new annotation helps to differentiate the handling of connection
level frames (SETUP and METADATA_PUSH) from the 4 stream requests.
Closes gh-23177
This commit renames RSocketRequester.RequestSpec data extension to
dataWithType to avoid shadowing issues and adds Publisher<T> and Flow<T>
variants to provide automatic reified type parameter resolution for
those types. It also makes RSocketRequester consistent with the
changes introduced via 2b4d6ce354 in WebFlux.
The commit deprecates syncBody(Object) in favor of body(Object)
which has the same behavior in ServerResponse, WebClient and
WebTestClient. It also adds body(Object, Class) and
body(Object, ParameterizedTypeReference) methods in order to support
any reactive type that can be adapted to a Publisher via
ReactiveAdapterRegistry. Related BodyInserters#fromProducer
methods are provided as well.
Shadowed Kotlin body<T>() extensions are deprecated in favor of
bodyWithType<T>() ones, including dedicated Publisher<T> and
Flow<T> variants. Coroutines extensions are adapted as well, and
body(Object) can now be used with suspending functions.
Closes gh-23212
Prior to this commit, if the user configured an empty path for the
targetRequestPath property of a FlashMap, the FlashMapManager threw a
StringIndexOutOfBoundsException when saving the output FlashMap for the
next request.
This commit fixes this by skipping the decoding and normalization of an
empty target request path.
Fixes gh-23240
Prior to Spring Framework 5.1.3, MimeTypeUtils.parseMimeTypes() and
MediaType.parseMediaTypes() ignored empty entries, but 5.1.3 introduced
a regression in that an empty entry -- for example, due to a trailing
comma in the list of media types in an HTTP Accept header -- would result
in a "406 Not Acceptable" response status.
This commit fixes this by filtering out empty entries before parsing
them into MimeType and MediaType instances. Empty entries are therefore
effectively ignored.
Fixes gh-23241
Use a callback to detect token authentication (via inteceptor) thus
avoiding a potential race between that detection after the message is
sent on the inbound channel (via Executor) and the processing of the
CONNECTED frame returned from the broker on the outbound channel.
Closes gh-23160
Improve the performance of `FormContentFilter` by checking directly if
`contentType` is empty. This saves the need for an exception to thrown
then immediately caught.
Closes gh-23216
Update `MimeTypeUtils` so that the StringUtils.hasLength check is
performed immediately on the incoming argument, rather than in
`parseMimeTypeInternal`. This restores the `IllegalArgumentException`
rather than the `NullPointerException` which is thrown by the
`ConcurrentHashMap`.
Closes gh-23215
See gh-23211
Commit 5008423408 added support for
multipart/* media types in FormHttpMessageConverter, but users still had
to manually register multipart/mixed as a supported media type in order
to POST multipart data with that content type.
This commit removes the need to manually register multipart/mixed as a
supported media type by registering it automatically in
FormHttpMessageConverter. In addition, this commit introduces
MULTIPART_MIXED and MULTIPART_MIXED_VALUE constants in MediaType.
Closes gh-23209
This commit improves the cache implementation by skipping the ordering
of most recently used cached keys when the cache is at least half empty.
See gh-23211
As of gh-22340, `MimeTypeUtils` has a built-in LRU cache implementation
for caching parsed MIME types and avoiding excessive garbage creation at
runtime.
This implementation, when hit with highly concurrent reads on the same
media type (the cache key), can create multiple keys for the same MIME
type string. This duplication leads to the cache filling up and evicting
entries. When the cache fetches a duplicate key, it is then not
associated with a value and the cache can return a `null` value, which
is forbidden by the API contract.
This commit adds another cache check within the write lock: this avoids
creating duplicate entries in the cache and `null` return values.
Fixes gh-23211
The responding side now relies on a new MetadataExtractor which decodes
metadata entries of interest, and adds them to an output map whose
values are then added as Message headers, and are hence accessible to
controller methods.
Decoded metadata entry values can be added to the output map one for
one, or translated to any number of values (e.g. JSON properties),
as long as one of the resulting pairs has a key called "route".
On the requesting side, now any metadata can be sent, and a String
route for example is not required to be provided explicitly. Instead
an application could create any metadata (e.g. JSON properties) as long
as the server can work out the route from it.
The commit contains further refinements on the requesting side so that
any mime type can be used, not only composite or routing metadata, e.g.
a route in an "text/plain" entry.
Closes gh-23157
Prior to this commit, the Basic Authentication credentials were encoded
for each request.
This commit addresses this minor performance issue by caching the
encoded credentials in BasicAuthenticationInterceptor.
In addition, this commit introduces new encodeBasicAuth() and
setBasicAuth(String encodedCredentials) methods in HttpHeaders to
support this feature.
Closes gh-23204
Prior to this commit, RestTemplate posted multipart with Content-Type
"multipart/form-data" even if the FormHttpMessageConverter configured
in the RestTemplate had been configured to support additional multipart
subtypes. This made it impossible to POST form data using a content
type such as "multipart/mixed" or "multipart/related".
This commit addresses this issue by updating FormHttpMessageConverter
to support custom multipart subtypes for writing form data.
For example, the following use case is now supported.
MediaType multipartMixed = new MediaType("multipart", "mixed");
restTemplate.getMessageConverters().stream()
.filter(FormHttpMessageConverter.class::isInstance)
.map(FormHttpMessageConverter.class::cast)
.findFirst()
.orElseThrow(() ->
new IllegalStateException("Failed to find FormHttpMessageConverter"))
.addSupportedMediaTypes(multipartMixed);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("field 1", "value 1");
parts.add("file", new ClassPathResource("myFile.jpg"));
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(multipartMixed);
HttpEntity<MultiValueMap<String, Object>> requestEntity =
new HttpEntity<>(parts, requestHeaders);
restTemplate.postForLocation("https://example.com/myFileUpload", requestEntity);
Closes gh-23159
This commit changes the new addSupportedMediaType(MediaType) method
to addSupportedMediaTypes(MediaType...), in order to allow registration
of multiple supported media types simultaneously.
See gh-23203
Prior to this commit, it was unclear that an invocation of getCache()
might potentially create a new Cache.
This commit updates the Javadoc to point out that concrete CacheManager
implementations may choose to create a new Cache at runtime if the Cache
does not already exist.
Closes gh-23193
This commit clarifies the semantics of the PriorityOrdered interface
with respect to sorting sets of objects containing both PriorityOrdered
and plain Ordered objects.
Closes gh-23187
Prior to this commit, all clients of
ControllerAdviceBean.findAnnotatedBeans() sorted the returned list
manually. In addition, clients within the core Spring Framework
unnecessarily used AnnotationAwareOrderComparator instead of
OrderComparator to sort the list.
This commit presorts the ControllerAdviceBean list using OrderComparator
directly within ControllerAdviceBean.findAnnotatedBeans().
Closes gh-23188
Prior to this commit, there would be no easy way to register client
RSocket handlers against an `RSocketRequester` instance. The only
solution was to gather all handlers and wrap them in a
`RSocketMessageHandler` and configure it as an acceptor on the client
RSocket.
This commit adds a convenience method on the `RSocketRequester` builder
to tkae care of this part of the infrastructure.
Closes gh-23170
Prior to this commit, the resolveBean() method in ControllerAdviceBean
looked up the @ControllerAdvice bean instance in the ApplicationContext
by name for every web request that involved lookups for global methods
annotated with @ExceptionHandler, @InitBinder, and @ModelAttribute.
This commit avoids the need for such repeated lookups in the
ApplicationContext by caching the resolved @ControllerAdvice bean
instance within ControllerAdviceBean once it has been resolved.
This commit introduces unit tests for the status quo in
ControllerAdviceBeanTests to serve as regression tests for future
changes to ControllerAdviceBean.
This commit adds retrieveMono and retrieveFlux reified variants, and
turns dataFlow(flow: Flow) extension into a general purpose reified
data(producer: Any) one.
Closes gh-23164
This commit introduces Flux<Part> ServerRequest.parts() that delegates
to ServerWebExchange.getParts() and offers an alternative,
streaming way of accessing multipart data.
Closes gh-23131
Create annotation.support sub-package and move handler code there. This
prepares for a future, functional handler (responder) variant and is
consistent with the package structure under simp.
Prior to this commit, `PathPattern::extractPathWithinMapping`
would always use the default path pattern separator `/` when extracting
the path within the pattern of a matched route.
This commit ensures that `PathPattern` uses the configured separator
when extracting the path within the matched mapping.
Fixes gh-23168
Prior to this commit, the `PathPatternRouteMatcher` would always use the
default path pattern separator when parsing incoming route strings to
`RouteMatcher.Route` instances.
When the `PathPatternRouteMatcher` is configured with a
`PathPatternParser` that has a custom separator (e.g., `.`), then the
matching algorithm can't match routes against parsed patterns.
This commit ensures that the route matcher uses the configured separator
at all times.
Fixes gh-23167
1. Consolidate config options for handler detection in the base class
AbstractMethodMessageHandler with sub-classes like RSocketMessageHandler
now only setting the handler predicate by default (e.g. @Controller).
2. Remove autoDetection flag in favor of just having the mutually
exclusive handler Predicate<Object> vs manually registered List<Object>.
Or if both are desired for some reason, then manually register first,
and set the predicate second.
Replace the Publisher argument in RequestSpec's
data(Publisher, Class<T>) and
data(Publisher, ParameterizedTypeReference<T>) methods with Object thus
allowing any reactive type known to the ReactiveAdapterRegistry to be
passed in directly rather than adapted to Publisher first.
As of 1.3.40, Kotlin now provides a kotlin-scripting-jsr223-embeddable
dependency which:
- Fixes classloading related issues
- Provides out of the box JSR 223 support
- Is compatible with Spring Boot Fat Jar mechanism
This commit updates Spring Framework tests and documentation accordingly.
Closes gh-23165
This commit removes the MessageHandlerAcceptor sub-class of
RSocketMessageHandler, and rather than implementing directly the
contracts for RSocket client and server acceptors, RSocketMessageHandler
now exposes clientAcceptor() and serverAcceptor() methods that return
the required adapter instances.
This provides better separation between the RSocketMessageHandler and
the RSocket adapter code, and also avoids implementing generic
interfaces like the BiFunction required for the client acceptor.
This commit introduces an overloaded jsonPath() method to specify a
target type to coerce into for MockMvcResultMatchers.
- jsonPath(String, Matcher<T>, Class<T>)
Closes gh-23141
Prior to this commit, RestTemplate and HttpMessageConverterExtractor did
not validate that the supplied HttpMessageConverter list contained no
null elements, which can lead to a NullPointerException when the
converters are accessed.
This commit improves the user experience by failing immediately if the
supplied HttpMessageConverter list contains a null element. This applies
to constructors for RestTemplate and HttpMessageConverterExtractor as
well as to RestTemplate#setMessageConverters().
Note, however, that RestTemplate#getMessageConverters() returns a mutable
list. Thus, if a user modifies that list so that it contains null values,
that will still lead to a NullPointerException when the converters are
accessed.
This commit also introduces noNullElements() variants for collections in
org.springframework.util.Assert.
Closes gh-23151
This commit documents which attributes in @Transactional are supported
for test-managed transactions in the Spring TestContext Framework (TCF).
Closes gh-23149
This commit makes sure that in DefaultMultipartMessageReader's
DefaultFilePart, the file is not closed before all bytes are written,
by using DataBufferUtils.write (see c1b6885191d6a50347aeaa14da994f0db88f26fe).
The commit also improves on the logging of the
DefaultMultipartMessageReader.
Closes gh-23130
Prior to this commit, if a subclass of
org.springframework.web.servlet.view.AbstractView or
org.springframework.web.reactive.result.view.AbstractUrlBasedView
configured a custom value for the requestContextAttribute, that value
was overwritten with null whenever the View was dynamically
instantiated by a UrlBasedViewResolver, and this could lead to
confusing behavior for users of the View.
This commit addresses this issue by ensuring that the
UrlBasedViewResolvers in spring-webmvc and spring-webflux do not
override the requestContextAttribute in a View if the
UrlBasedViewResolver has not been explicitly configured with a custom
requestContextAttribute value.
Closes gh-23129
This commit improves the FreeMarker macro support in spring-webflux by
automatically exposing a RequestContext under the name
"springMacroRequestContext" for use with Spring's FreeMarker macros in
spring.ftl.
This aligns with the user experience for FreeMarkerView in spring-webmvc.
Closes gh-23105
Prior to this commit, exceptions thrown while closing an InputStream in
AbstractResource were silently ignored.
This commit improves diagnostics for such failure scenarios by logging
the exception at DEBUG level.
Closes gh-23116
Update `FormatterRegistry` with `addPrinter` and `addParser` methods
that can be used to register Printer or Parser implementations in a
similar way to the existing `addFormatter` method.
Closes gh-23110
This commit improves FreeMarkerConfigurerTests in spring-webmvc by
testing against FreeMarkerConfigurer instead of
FreeMarkerConfigurationFactoryBean and moves the original
FreeMarkerConfigurationFactoryBeanTests to spring-context-support in
the org.springframework.ui.freemarker package.
Closes gh-23073
Prior to this commit, MockHttpServletRequest.setCookies() produced one
Cookie header per supplied cookie, resulting in multiple Cookie headers
which violates the specification.
This commit fixes this by ensuring that all cookie name-value pairs are
stored under a single Cookie header, separated by a semicolon.
Closes gh-23074
This commit allows to configure a custom path separator when parsing and
matching path patterns with `PathPatternParser`, but also when parsing
incoming paths as `PathContainer` instances.
Closes gh-23092
1. Add contentType and filename options to PartBuilder.
2. Revert recently committed #44659f since asyncPart can't properly
support Publisher of Part (only Mono, can't support filename), and
replace that with support for Part in the regular part method.
Closes gh-23083
Beginning with Spring Framework 5.0, non-null checks for the
requiredType in the following methods were inadvertently removed with
the internal switch to ResolvableType.forRawClass(requiredType).
- BeanFactory.getBean(Class<T>, Object...)
- BeanFactory.getBeanProvider(Class<T>)
- AutowireCapableBeanFactory.resolveNamedBean(Class<T>)
This commit restores those non-null checks.
Closes gh-23045
This commit introduces support for consistent ordering of Properties
created by CollectionFactory.createStringAdaptingProperties().
Specifically, the created Properties instance sorts properties
alphanumerically based on their keys.
Closes gh-23081
This commit adds a new constructor to `JettyClientHttpConnector` and
deprecates another one. Jetty is not creating `HttpClient` instances
using a builder API, but rather setting immutable configuration at
constructor time and using setters for the rest.
This commit addresses that by deprecating the constructor variant
accepting a `Consumer` and just delegating to Spring's implementation
for setting the client resources as needed.
Closes gh-22977
This commit migrates to the MockitoJUnitRunner where sensible, which
will later allow for an easier migration to Mockito's extension for
JUnit Jupiter.
In addition, this commit deletes unnecessary stubbing for various mocks
and polishes test fixture setup in various test classes.
This commit introduces an internal SortedProperties class that is a
specialization of java.util.Properties which sorts properties
alphanumerically based on their keys.
This can be useful when storing a java.util.Properties instance in a
properties file, since it allows such files to be generated in a
repeatable manner with consistent ordering of properties.
Comments in generated properties files can also be optionally omitted.
An instance of SortedProperties can be created via two new
createSortedProperties() factory methods in
org.springframework.core.CollectionFactory.
Closes gh-23018
Update `AnnotationTypeMapping` so that instance comparisons are no
longer used when checking attribute methods. Prior to this commit,
in an environment with tightly constrained memory, the method cache
could be cleared and different method instances would be returned.
Closes gh-23010
Rename some `MergedAnnotation` methods to prevent using parent/child
terminology, specifically:
`getDepth()` has been renamed `getDistance()`
`getParent()` has been renamed `getMetaSource()`
`getTypeHierarchy()` has been renamed `getMetaTypes()`
The parent child naming was particularly confusing given that the
parent/child relationships were inverted from the way that a lot of
users think about meta-annotations. For example, a `@RequestMapping`
having a parent of `@GetMapping` feels odd given that `@GetMapping`
is the thing declaring the meta-annotation relationship.
The new method names are designed to align more closely with existing
terms. For example, `getMetaSource` hints at the relationship with
`isMetaAnnotated` and `getSource`.
Closes gh-22946
This commit introduces a getOrEmpty(String) method in HttpHeaders that
returns an immutable, empty list if no values are present for the
specified header name. This is provided as a convenience over the
existing get(String) method which returns null in such cases.
Closes gh-22949
Aligns ReactiveAdapterRegistry with MVC/messaging handler methods in terms of recognizing CompletionStage as well as CompletableFuture. Includes consistent use of ReactiveAdapter for reactive transactions.
Closes gh-23011
ViewResolutionResultHandler no longer adds BindingResult objects for
async model attributes. Instead AbstractView adds them later when
those attributes are resolved to concrete values.
Closes gh-22933
EncoderHttpMessageWriter takes advantage of the Encoder#encodeValue
that's new in 5.2 in order to produce a Mono<DataBuffer> instead of
producing a Flux<DataBuffer> and then using flux.singleOrEmpty().
Closes gh-22952
* Added DataBufferUtils.split variant that takes multiple delimiters
as argument (instead of 1).
* Use this new split() variant from within StringDecoder, replacing
its inefficient algorithm with the Knuth-Morris-Pratt algorithm.
This commit adds Checkstyle rules to disallow imports of the following.
- junit.framework.*
- org.junit.Assert.assertThat
- org.junit.Assume.assumeThat
See gh-22894
Prior to this commit, HeaderResultMatchers had a direct dependency on
org.junit.Assert which forces JUnit 4 to be present on the classpath.
This commit fixes this by introducing assertNotNull() in
org.springframework.test.util.AssertionErrors and delegating to that
instead.
Fixes gh-22932
Organize test imports to expand all '.*' static imports into
fully qualified imports.
This update will allow us to use additional checkstyle rules in
the future, and will also help if we migrate fully to AssertJ.
DefaultCacheAwareContextLoaderDelegate now logs the identity hash code
for an application context instance that was stored in or retrieved from
the context cache in the Spring TestContext Framework.
Closes gh-22925
* Add limited checkstyles to test code
Add a limited set of checkstyle rules to the test codebase to improve
code consistency.
* Fix checksyle violations in test code
* Organize imports to fix checkstyle for test code
* Migrate to assertThatExceptionOfType
Migrate aware from ExpectedException rules to AssertJ exception
assertions. Also include a checkstyle rules to ensure that the
the ExpectedException is not accidentally used in the future.
See gh-22894
Prior to this commit, dependency injection of all arguments in a test
class constructor invoked by JUnit Jupiter was only possible if the
constructor was explicitly annotated with @Autowired.
This commit introduces support for a configurable "test constructor
autowire" mode which defaults to false in order to remain backwards
compatible.
Specifically, this mode can be configured globally for an entire test
suite via a new "spring.test.constructor.autowire" JVM system property
that can alternatively be configured via the SpringProperties
mechanism. In addition, the global "test constructor autowire" mode can
be overridden locally on a per-class basis via the new @TestConstructor
annotation.
Closes gh-22286
DefaultMultipartMessageReader does not cache the part contents, so
binding to the same part multiple times does not work.
Rewrote this test to use separate HTTP request instead.
Normally consumes matches the "Content-Type" header but what should be done if
there is no content? This commit adds checks for method parameters with
@RequestBody(required=false) and if "false" then also match requests with no content.
Closes gh-22010
Deprecate the public `StandardMetadata` constructors to make it clearer
that these classes should not be instantiated directly. A new
`AnnotationMetadata.introspect` factory method has been added which
can now be used to obtain instances.
This change will allow use to make the constructors package private
and drop the `nestedAnnotationsAsMap` parameter in a future release.
Closes gh-22906
Replace the existing ASM based readers with new implementations that
also support MergedAnnotations. The meta-data classes themselves are
now immutable, and constructed via separate reader classes.
The `SimpleMetadataReader` class has been updated to return the new
classes, however the old ones remain since some of them are public
and might be being used directly.
Closes gh-22884
Add `AnnotatedTypeMetaData.getAnnotations()` that can be used to access
annotation details using the `MergedAnnotations` interface.
Where possible, the existing annotation methods have been migrated to
call `getAnnotation()`, rather than needing their own implementation.
The existing ASM based meta-data implementations have not been updated
since they will be deprecated and replaced in a subsequent commit.
See gh-22884
Update `StandardAnnotationMetadata` to use `ReflectionUtils` when
obtaining declared methods. This update is primarily so that the common
method cache can be used.
Closes gh-22907
Update `StandardAnnotationMetadata` and `AnnotationMetadataReadingVisitor`
so that `java.lang.annotation` annotations are consistently skipped.
Closes gh-22885
Update ASM based metadata readers so that only RetentionPolicy.RUNTIME
annotations are exposed. This aligned behavior with the reflection based
implementation.
Closes gh-22886
Add a factory method to `MergedAnnotation` that allows an instance to
be created for an explicit collection of root annotations. This method
will allow ASM based readers to expose a `MergedAnnotation` instance
that has root annotations loaded from bytecode, and meta-annotations
loaded using reflection.
See gh-22884
Update TypeMappedAnnotation so that Strings can be used to represent
Class attribute values. This will allow ASM annotation readers to
present a `MergedAnnotation` instance without necessarily having the
actual class values on the classpath.
When the underlying value is a String, any calls to
`getValue(name, String.class)` or `asMap(Adapt.CLASS_TO_STRING)` will
simply return the original String. Calls that need the actual Class
result (such as `getClass`) will use `Class.forName` and may throw
a `ClassNotFoundException` at that point.
This commit also allows an empty Object[] to be used to represent
any empty primitive array.
See gh-22884
Rename `from` to `of` for the `MergedAnnotation` factory methods that
work with Maps. The previous name was a little confusing, especially
when an annotation source parameter was specified. The new method name
helps to make it clearer when the user is explicitly defining the
attributes of the annotation, as opposed to picking them up from the
source.
Add a `getTypeHierarchy()` method to `MergedAnnotation` that can be used
to return the full type hierarchy information. This method is
specifically designed to be used in combination with
`MergedAnnotationPredicates.unique`.
This update also allows us to delete the `parentAndType` method
from `AnnotatedElementUtils`.
Closes gh-22908
We now correctly unwrap suspended resources instead capturing
the Mono emitting suspended resources.
We also properly continue resume by chaining resume Mono's
instead of terminating eagerly.
This commit introduces the DefaultMultipartMessageReader, a fully
reactive multipart parser that does have any third party dependencies.
Closes gh-21659
Added two methods to DataBufferUtils:
* matcher(byte[]), which returns a Matcher object that can be used to
find a delimiter in a data buffer.
* split(Publisher<DataBuffer>, byte[] delimiter), which splits a given
stream of data buffers around a given delimiter.
We now use Flux.usingWhen() instead materialize/dematerialize operators
to reuse Reactor's resource closure.
Until usingWhen() accepts a BiFunction to consume error signals,
we need to map error signals outside of usingWhen which requires
re-wrapping of the ReactiveTransaction object.
Also, reuse the current TransactionContext to leave Transaction
creation/propagation entirely to ReactiveTransactionManager instead
of creating new TransactionContexts.
This commit defers flushing of the response until the first item is
emitted that needs to be written (and flushed) to the response.
This makes Spring MVC consistent with WebFlux in this regard.
Closes gh-21972
ServerRequest:
- awaitPrincipalOrNull is renamed to awaitPrincipal since
there is no non-nullable variant
ServerResponse:
- new BodyBuilder.sse() extension
- BodyBuilder.bodyToServerSentEvents is deprecated in favor
of sse().body()
- BodyBuilder.bodyAndAwait(flow: Flow<T>) is renamed to
bodyFlowAndAwait to avoid shadowing of
BodyBuilder.bodyAndAwait(body: Any)
- BodyBuilder.bodyToServerSentEventsAndAwait is removed,
sse().bodyAndAwait() should be used instead
Closes gh-22899
We now use Flux.usingWhen() instead materialize/dematerialize operators
to reuse Reactor's resource closure.
Until usingWhen() accepts a BiFunction to consume error signals,
we need to map error signals outside of usingWhen which requires
re-wrapping of the ReactiveTransaction object.
Such a static unmodifiable TransactionDefinition with defaults can be used for getTransaction(null) calls, now also possible for getReactiveTransaction. Furthermore, it can be used for a simple TransactionalOperator.create(ReactiveTransactionManager) method without an internal dependency on the transaction.support package.
See gh-22646
Introduces TransactionManager marker interface for PlatformTransactionManager as well as ReactiveTransactionManager, allowing for a common configuration type in TransactionAspectSupport and TransactionManagementConfigurer.
Closes gh-22590
Introduces TransactionExecution base interface for TransactionStatus as well as ReactiveTransaction. Renames getTransaction method to getReactiveTransaction, allowing for combined implementations of PlatformTransactionManager and ReactiveTransactionManager.
See gh-22646
This commit adds SPI interfaces to support reactive transactions
through spring-tx with optional dependencies to Project Reactor and
supportive implementations for TransactionalOperator and
AbstractReactiveTransactionManager.
Prior to this when SpEL compiled an expression using the numeric
operators <, >, <= or >= then it would not create code that handled
nulls. Nulls can occur if a boxed numeric operand is used prior
to compilation, then it is nulled out. SpEL now creates null
handling bytecode.
Closes gh-22358
This commit deprecates MediaType.APPLICATION_JSON_UTF8 and
MediaType.APPLICATION_PROBLEM_JSON_UTF8 in favor of
MediaType.APPLICATION_JSON and MediaType.APPLICATION_PROBLEM_JSON since
UTF-8 encoding is now handled correctly by most browsers
(related bug has been fixed in Chrome since September 2017).
MediaType.APPLICATION_JSON is now used as the default JSON content type.
Closes gh-22788
Remove the dataMimeType argument on connect methods. Applications can
still configure it through the ClientRSocketFactory but it shouldn't
be necessary as we now choose a default MimeType from the supported
encoders and decoders.
Add an option to provide the RSocketStrategies instance (vs customizing
it) which is expected in Spring config where an RSocketStrategies
instance may be shared between client and server setups.
This commit adds CBOR reactive support for single value only in
order to allow CBOR usage in RSocket. Notice that no CBOR support
is configured on WebFlux, this will require gh-20513 to be resolved.
Closes gh-22767
This commit leverages Flux instead of Flow to support suspending
handler methods returning Flow in order to avoid multiple invocations
of the suspending function on every collect().
See gh-22820
Prior to this commit, `RSocketRequester` would have a single
`RSocketRequester.create` static method taking a fully built
`RSocket` as an argument. Developers need to build an `RSocket`
instance using the `RSocketFactory` and then use it to create
a requester.
To help developers set up a requester, this commit adds a new
`RSocketRequester.Builder` interface and implementation. The
`RSocket` building phase and codecs configuration are part of a
single call chain. Subscribing to the returned
`Mono<RSocketRequester>` will configure and connect to the remote
RSocket server.
This design should be improved in gh-22798, since we will need to
support metadata in a broader fashion.
Closes gh-22806
Support for suspending handler methods introduced in Spring
Framework 5.2 M1 does not detect types correctly and does not
support suspending handler methods returning Flow which is a
common use case with WebClient.
This commit fixes these issues and adds Coroutines integration
tests.
Closes gh-22820
Closes gh-22827
Following on 3ebbfa2191 where the local
refCount was removed in favor of using the internal refCount of the
native data buffer, this commit ensures that LeakAwareDataBufferFactory
uses a PooledDataBufferFactory delegate by default.
There are also fixes for test issues with eager allocation uncovered by
these changes in StringDecoder and ResourceDecoder.
This commit removes the @Deprecated declaration on the
org.springframework.mock.jndi package, since such usage results in a
compiler warning on JDK 9+ which breaks Spring's JDK 9 and JDK 11 CI
builds.
https://bugs.openjdk.java.net/browse/JDK-6481080
See gh-22779
LeakAwareDataBuffer was keeping its own refCount rather than checking
through the delegate. This leads to false leak reports in a sequence
where an allocated buffer is retained and then sliced since it is not
aware of the changes to the refCount through the slice.
Use of Flux.just is problematic in that if the Flux is cancelled before
demand, the item may never be read, nor freed. Flux#just does not
even delegate cancellation signals.
Closes gh-22731
Prior to this commit, the pattern destination variables were not set in
the message headers prior to calling the handler. In this case, the
`DestinationVariableMethodArgumentResolver` could not get the
destination variables from the message headers and resolve those as
handler arguments.
This commit mutates the message headers if the message destination
contains patterns.
Fixes gh-22776
An empty path mapping in an @RequestMapping now consistently matches to
empty paths regardless of whether there are both type and method level,
annotations, or method-level only.
Closes gh-22543
This commit moves the WebFlux getMappingPathPatterns() implementation
from RequestMappingHandlerMapping to
RequestMappingInfoHandlerMapping so that subclasses of the latter no
longer need to re-implement the method.
See gh-22543
This commit configures the Kotlin plugin for Eclipse in the
spring-core-coroutines Gradle project so that users no longer have to
manually "Configure Kotlin / Add Kotlin Nature" within the Eclipse IDE
after importing projects.
This change is currently limited to the spring-core-coroutines project
since it is the only project in which Java code depends on compiled
Kotlin code; however, this change may later be applied to additional
projects if desirable.
Due to the changes in a7425c81c0, we no
longer need to execute tests using the JMXMP protocol in PERFORMANCE
builds.
This commit removes the JMXMP constant from the TestGroup enum and
updates affected tests, thereby effectively including such tests in
the standard build from now on.
See gh-22757
This commit introduces a publishEvent() method in the TestContext API
as a convenience for publishing an ApplicationEvent to the test's
ApplicationContext but only if the ApplicationContext is currently
available and with lazy creation of the ApplicationEvent.
For example, the beforeTestClass() method in
EventPublishingTestExecutionListener is now implemented as follows.
public void beforeTestClass(TestContext testContext) {
testContext.publishEvent(BeforeTestClassEvent::new);
}
Closes gh-22765
Although the jmxremote_optional JAR has been added to the build agents
on the Bamboo CI server for the latest JDK 8 installation, that
solution is brittle since it has to be manually installed in every new
JDK installation. In addition, this approach will not work with JDK 9+
since the "Extension Mechanism" has been removed beginning with JDK 9.
https://docs.oracle.com/javase/10/migrate/toc.htm#JSMIG-GUID-2C896CA8-927C-4381-A737-B1D81D964B7B
This commit addresses this issue by adding the following dependency to
spring-context.
// Substitute for "javax.management:jmxremote_optional:1.0.1_04" which
// is not available on Maven Central
testRuntime("org.glassfish.external:opendmk_jmxremote_optional_jar:1.0-b01-ea")
With this change, the Spring PERFORMANCE builds now execute on JDK 8,
9, and 11.
See gh-22757
This commit registers the EventPublishingTestExecutionListener as a
default TestExecutionListener with an order of 10,000. This registers
the EventPublishingTestExecutionListener as the last listener provided
by the Spring Framework.
With EventPublishingTestExecutionListener registered with an order of
10,000, it is effectively wrapped by all other Spring listeners,
including support for @DirtiesContext and test-managed transactions.
Furthermore, this commit revises the implementation of
EventPublishingTestExecutionListener to take advantage of the new
TestContext#hasApplicationContext() support which allows the
EventPublishingTestExecutionListener to publish events only if the
test's ApplicationContext is currently available. This avoids
undesirable side-effects such as eager loading of the
ApplicationContext before it is needed or re-loading of the
ApplicationContext after it has been intentionally closed.
Closes gh-18490
This commit introduces support in the Spring TestContext Framework
(TCF) to query whether the test's ApplicationContext is available.
Specifically, this commit introduces the following two `default`
methods along with corresponding implementations in DefaultTestContext
and DefaultCacheAwareContextLoaderDelegate.
- `boolean hasApplicationContext()` in the TestContext API
- `boolean isContextLoaded(MergedContextConfiguration)` in the
CacheAwareContextLoaderDelegate API
Closes gh-22756
This commit revises the signature of getMappingPathPatterns() in
AbstractHandlerMethodMapping to return a set of PathPatterns instead of
a set of Strings.
See gh-22543
Add a convenience method that allows a `MergedAnnotation` to be
converted into an `AnnotationAttributes` instance. Also rename
the `MapValues` enum to `Adapt` which generally seems to read
better.
Closes gh-22738
Commit c0b52d09f5 introduced support for
throwing an exception if a @RequestMapping handler method in a Spring
MVC controller was mapped to an empty path. This had negative side
effects for applications that intentionally mapped to an empty path,
potentially alongside a mapping to an explicit path for the same
handler method.
This commit addresses this by logging a warning (instead of throwing an
exception) if a @RequestMapping method is mapped only to empty paths.
This commit also introduces the same support for WebFlux-based
@RequestMapping handler methods.
Closes gh-22543
Includes bringing registerBean constructor-vararg variants up to GenericApplicationContext, making AnnotationConfigApplicationContext a straightforward subclass with a single template method to override.
See gh-22457
Normally failed requests fail the test but they're suppressed for some
reason (e.g. in async callback) then verify should still correctly
report the failures.
Closes gh-21799
Flow is a Kotlin Coroutines related cold asynchronous
stream of the data, that emits from zero to N (where N
can be unbounded) values and completes normally or with
an exception.
It is conceptually the Coroutines equivalent of Flux with
an extension oriented API design, easy custom operator
capabilities and some suspending methods.
This commit leverages Flow <-> Flux interoperability
to support Flow on controller handler method parameters
or return values, and also adds Flow based extensions to
WebFlux.fn. It allows to reach a point when we can consider
Spring Framework officially supports Coroutines even if some
additional work remains to be done like adding
interoperability between Reactor and Coroutines contexts.
Flow is currently an experimental API that is expected to
become final before Spring Framework 5.2 GA.
Close gh-19975
Prior to this commit, handler methods in Spring MVC controllers were
not required to provide explicit path mappings via @RequestMapping (or
any of its specializations such as @GetMapping). Such handler methods
were effectively mapped to all paths. Consequently, developers may have
unwittingly mapped all requests to a single handler method.
This commit addresses this by enforcing that @RequestMapping methods
are mapped to an explicit path. Note, however, that this is enforced
after type-level and method-level @RequestMapping information has been
merged.
Developers wishing to map to all paths should now add an explicit path
mapping to "/**" or "**".
Closes gh-22543
WebFlux.fn RouterFunctionDsl#invoke and CoRouterFunctionDsl#invoke
were wrongly exposed on public API and have never been designed to
be used by end users, but rather only invoked from router { } or
coRouter { } builders.
To fix that, avoiding this method being accessible from the DSL and
for the sake of consistency with WebMvc.fn RouterFunctionDsl,
Spring Framework 5.2 turns public fun invoke() method to
an internal fun build() one.
As a consequence RouterFunctionDsl and CoRouterFunctionDsl are not
open anymore, they are expected to be extended via Kotlin
extensions if needed.
Closes gh-22736
LogMessage is an abstract class now: with internal subclasses for Supplier bindings as well as printf-style format strings with a variable number of arguments (some fixed for efficiency, varargs array as fallback), created through corresponding static factory methods.
Closes gh-22726
As of 5.2, ListableBeanFactory.findAnnotationOnBean and its retrieval companions getBeanNamesForAnnotation and getBeansWithAnnotation detect annotations on @Bean methods as well.
Closes gh-22541
This commit changes the main configuration classes for Spring MVC and
Spring WebFlux to not call other bean methods when setting up the web
infrastructure. This allows configuration classes extending
`DelegatingWebFluxConfiguration` and `DelegatingWebMvcConfiguration`
to opt-in the lite-mode, as introduced in gh-22461.
This commit updates the class-level Javadoc for
EventPublishingTestExecutionListener in order to provide explicit
documentation for exception handling and async support.
See gh-18490
1. If the write Subscriber cancels with the item cached, release it.
2. If the write Publisher emits an error while the item is cached, when
the write Subscriber subscribes, release the cached item and emit the
error signal.
Closes gh-22720
This commit improves CORS support by:
- Using CORS processing only for CORS-enabled endpoints
- Skipping CORS processing for same-origin requests
- Adding Vary headers for non-CORS requests
It introduces an AbstractHandlerMapping#hasCorsConfigurationSource
method in order to be able to check CORS endpoints efficiently.
Closes gh-22273
Closes gh-22496
As of Coroutines 1.2.0-alpha, Dispatchers.Unconfined
is a stable API so we can leverage it in order to get
better performances in our Reactive to Coroutines
bridge.
See gh-19975
The cancellation callback in asynchronousReadFileChannel must be called
before the first read I/O or otherwise if cancellation signals happens
immediately the onDispose callback may be missed.
The DefaultBufferFactory workaround however remains in place until an
expected additional fix arrives with Reactor Core 3.2.9.
See gh-22107
Update `AnnotationUtils` so that `RepeatableContainers.none()` is used
when performing an exhaustive search for merged annotations. These
parameters were accidentally removed in commit 210b1789 and weren't
caught earlier because we were missing a test.
Closes gh-22702
Update `addConventionAnnotationValues` so that `value` attributes
do not override existing annotation values. The aligns the new
`MergedAnnotations` API with the previous `AnnotatedElementUtils`
logic.
Closes gh-22703
Following a response on
https://github.com/reactor/reactor-core/issues/1634 apparently
FluxSink is respecting doOnDiscard but there is a race condition
in DataBufferUtils with file reading.
This commit makes two changes:
1) Add more checks for onDispose to detect cancellation signals
as well as to deal with potentially concurrent such signal.
2) Do not close the channel through the Flux.using callback but
rather allow the current I/O callback to take place and only then
close the channel or else the buffer is left hanging.
Despite this tests still can fail due to a suspected issue in Reactor
itself with the doOnDiscard callback for FluxSink. That's tracked under
the same issue https://github.com/reactor/reactor-core/issues/1634
and for now the use of DefaultDataBufferFactory is enforced as a
workaround until the issue is resolved.
See gh-22107
Prior to this commit, the three `test` tasks in the spring-test module
shared the same output directory for test reports. This had the
negative side effect of causing Gradle to believe that the tasks were
not UP-TO-DATE. Consequently, all three `test` tasks in the spring-test
module were executed for every build even if there were zero changes in
the spring-test module.
This commit fixes this issue by allowing Gradle to use the default test
results output directory for each `test` task. Thanks to @marcphilipp
for providing the tip.
In addition, the Artifactory Gradle task in the Default Job of the
Bamboo build plan for the Spring Framework (SPR-PUB) has been updated
to use the following custom test results directory pattern:
`**/build/test-results/**/*.xml`.
See: https://guides.gradle.org/using-build-cache/#concepts_overlapping_outputs
This commit provides both nullable and non-nullable variants for
awaitBody, makes awaitPrincipal return type nullable and rename
awaitResponse to awaitExchange for better consistency with Java API.
See gh-19975
Update the internal proxy used in `TypeDescriptor` so that it returns a
cloned array for calls to `getDeclaredAnnotations` or `getAnnotations`.
Closes gh-22695
One is literally an alias for the other with "the advantage that a
protocol sniffer/discriminator will be able to differentiate the STOMP
connection from an HTTP connection".
Closes gh-22652
This commit updates Kotlin beans DSL in order to support
creating beans using callable references with autowired
parameters. Type resolution is implemented using Kotlin
reified type parameters without requiring reflection.
Closes gh-21845
This commit removes the constraint from type variables in
PropertyResolver, JdbcOperations and RestOperations
Kotlin extensions in order to get null-safety inferred
from the type declared by the user.
Closes gh-22687
Address issues where buffers are allocated (and cached somehow) at or
before subscription, and before explicit demand.
The commit adds tests proving the leaks and fixes. The common thread
for all tests is a "zero demand" subscriber that subscribes but does
not request, and then cancels without consuming anything.
Closes gh-22107
This commit introduces tests that verify that both
CssLinkResourceTransformer implementations properly handle empty url()
functions in CSS files.
See gh-22602
Includes deprecation of several AnnotationUtils methods and nullability refinements for passed-in function arguments at the MergedAnnotation API level... also, MergedAnnotation.getType() returns a Class now.
Closes gh-22663
Closes gh-22685
Prior to this commit, if a @ControllerAdvice implemented both
RequestBodyAdvice and ResponseBodyAdvice, it was registered twice in
RequestMappingHandlerAdapter.
This commit ensures that such instances are only registered once.
Closes gh-22638
Refine `TypeMappedAnnotation.getValueFromMetaAnnotation` to correctly
account for aliases when finding values from meta-annotations. Prior
to this commit, only convention based mappings were considered when
searching for values on meta-annotations. This meant that declared
meta-annotations that used aliases could return the "default value"
rather than the merged value.
Closes gh-22654
This commit introduces the spring-core-coroutines module
in order to avoid referencing Kotlin code from Java one,
which is currently not supported by Eclipse.
During the build, spring-core-coroutines is merged into
spring-core, so this change is expected to have no impact
for end users.
This module contains functions accessible from Java via
the CoroutinesUtils class to adapt Coroutines and Deferred
instances to and from Mono.
See gh-19975
Update the proxy used in `AnnotatedElementUtils.forAnnotations` so
that it returns a cloned array for calls to `getDeclaredAnnotations`
or `getAnnotations`. This matches the behavior of standard JDK
`AnnotatedElement` implementations.
Closes gh-22655
Namespace handlers are mapped based on the canonical names for XML
namespaces which in Spring do not use "https" as the scheme.
See gh-22617 gh-22622 gh-22635
Refine the element filtering performed by `AnnotationsScanner` to also
cover `org.springframework.util` and most `com.sun` classes which turn
out to be referenced quite frequently and which we know contain no
useful annotations.
See gh-21697
Add a cache to `BridgeMethodResolver` to help with repeated calls to
resolve the same methods. Since bridge method resolution can be somewhat
expensive (especially when resolving generics), and the number of bridge
methods is quite small, a cache generally helps.
This commit also simplifies the code a little by calling `doWithMethods`
directly rather than relying on `ReflectionUtils.getAllDeclaredMethods`
to do so. The methods list is now always created, but we save the list
creation that `getAllDeclaredMethods` used to do.
Closes gh-22579
Add an early exit to `StringUtils.cleanPath` to save array creating and
string concatenation. With a typical Spring application, the `cleanPath`
method can be called over 600 times, often with a path constructed by
a `ClassPathResource` that is likely to already be clean.
Closes gh-22568
Update `ConcurrentReferenceHashMap` to make some methods more inline
friendly, and to manually inline a few others. These minor optimizations
don't make a great deal of difference for most applications, but seem
worthwhile since we use `ConcurrentReferenceHashMap` for many internal
caches.
Closes gh-22566
Update `ConfigurationClassParser` to skip `java.lang.annotation` types
which were often processed but would never provide useful results. Also
use a single shared immutable `SourceClass` instance to represent
`Object.class`.
Closes gh-22563
Migrate all possible `AnnotationUtils` and `AnnotatedElementUtils`
method to the `MergedAnnotation` API, verify results against the old
implementations.
All migrated methods now call both the new API and the old version and
ensure that the same results or exceptions are raised. A full build of
both Spring Framework and Spring Boot has been executed to ensure, as
much as possible, that the migration does not cause unexpected
regressions.
See gh-22562
Create internal variants of the existing `AnnotationUtils` and
`AnnotatedElementUtils` classes and migrate the existing classes to
use them.
The internal variants will be used to check that the same results are
given as we migrate the utils methods to use the new `MergedAnnotations`
API.
See gh-22562
Add new `MergedAnnotations` and `MergedAnnotation` interfaces that
attempt to provide a uniform way for dealing with merged annotations.
Specifically, the new API provides alternatives for the static methods
in `AnnotationUtils` and `AnnotatedElementUtils` and supports Spring's
comprehensive annotation attribute `@AliasFor` features. The interfaces
also open the possibility of the same API being exposed from the
`AnnotationMetadata` interface.
Additional utility classes for collecting, filtering and selecting
annotations have also been added.
Typical usage for the new API would be something like:
MergedAnnotations.from(Example.class)
.stream(MyAnnotation.class)
.map(a -> a.getString("value"))
.forEach(System.out::println);
Closes gh-21697
Add a new test class to help cover annotation introspection failure
handling. These tests were previously missing and are important to
ensure that annotation util code changes don't introduce regressions.
See gh-21697
Add a public variant of `getDeclaredMethods` that defensively copies the
cached methods array. This is often more faster and more convenient
for users than calling `doWithLocalMethods`. We still retain most of the
benefits of the cache, namely fewer security manager calls and not as
many `Method` instances being created.
Closes gh-22580
As recommended by RFC 7231, this commit restore using 2 digit days
when formatting dates while still using
DateTimeFormatter.RFC_1123_DATE_TIME for parsing.
Closes gh-22478
This commit updates Jackson2ObjectMapperBuilder in order
to ensure that modules specified via modulesToInstall
eventually override the default ones.
Closes gh-22576
This commit adds support for HandlerFunctions and RouterFunctions to
DispatcherServlet, in the form of a HandlerAdapter and HandlerMapping.
See gh-21490
This commit introduces Servlet.fn, a servlet-based version of
WebFlux.fn, i.e. HandlerFunctions and RouterFunctions.
This commit contains the web framework only, further commits provide
tests and DispatcherServlet integration.
See gh-21490
Extend the list of disconnected client errors in HttpWebHandlerAdapter
to include the Reactor Netty AbortedException as well exceptions with
the message "connection reset by peer".
Closes gh-21790
Prior to this commit, documentation for WebJar support referenced the
webjars-locator artifact; however, Spring now uses the
webjars-locator-core artifact.
This commit updates the documentation to reflect this.
Closes gh-22613
Use the checkpoint operator at various places in WebFlux to insert
information that Reactor then uses to enrich exceptions, via suppressed
exceptions, when error signals flow through the operator.
Closes gh-22105
In line with the general trend toward favoring core JDK APIs for common
tasks in Spring Framework 5.2, this commit replaces handcrafted
statements with Math.min() and Math.max() were applicable.
Prior to this commit, the PDF version of the Spring Reference Manual
contained HTML <strong></strong> tags in code examples due to the fact
that Asciidoctor converts bold formatting (i.e., elements wrapped in
`**` or `*`) within source code blocks into HTML tags even for PDF
rendering.
This commit addresses this issue by removing all bold formatting from
example code blocks.
Closes gh-22577
Includes consistent bean class resolution in the enhancement step as well as general reflection optimizations for user-declared methods.
Closes gh-22420
The isCandidateClass mechanism is consistently used for a bypass check before method traversal attempts. While by default this is only bypassing standard java types, the same mechanism can be used with index metadata which indicates non-presence of certain annotations.
See gh-22420
This commit adds support for primitive default values for
BeanUtils.instantiateClass arguments in Java in order to provide
a consistent behavior in both Java and Kotlin languages.
Closes gh-22531
Prior to this commit the documentation for annotation-based include and
exclude filters used with component scanning did not explicitly mention
the fact that annotations are considered a match if they are either
present or meta-present on candidate classes.
This commit improves the documentation in this regard.
See gh-22551
Prior to this commit, the exception message generated by
instantiateFactory() in SpringFactoriesLoader did not report the
offending class in the top-level exception message. The offending class
was in fact included in the message of the nested exception, but the
top-level exception message on its own was a bit misleading.
This commit improves the diagnostics for such failures by including the
offending class and the target factory type in the top-level exception
message.
Closes gh-22453
Before this commit, the return type for Kotlin suspending functions
(as returned by MethodParameter#getParameterType and
MethodParameter#getGenericReturnType methods) was incorrect.
This change leverages Kotlin reflection instead of Java one
to return the correct type.
Closes gh-21058
- Integration tests run with zero copy configuration.
- RSocketBufferLeakTests has been added.
- Updates in MessagingRSocket to ensure proper release
See gh-21987
Simplify handling by eliminating the use of a message channel. Instead
MessageHandlerAcceptor now extends from RSocketMessageHandler and
delegates directly to it.
See gh-21987
Before this change if a controller method returned a Publisher whose
first signal was an error, the error signal would not be delegated to
a @MessageExceptionHandler method as expected.
To make this work for now we use a package private local copy of the
ChannelSendOperator from spring-web.
See gh-21987
The package o.s.messaging.handler.annotation.support was missing
@NonnullApi and @NonNullFields. This commit corrects that and also
adds @Nullable to methods and arguments as needed to address
warnings.
This commit introduces a `MockMvc` Kotlin DSL via a set of
extensions like `MockMvc.get` or `MockMvc.request`
that provide a Kotlin idiomatic and easily discoverable
API while staying close to the original Java API design.
Closes gh-1951
Prior to this commit, repeated calls to `DataBuffer.write(CharSequence,
Charset)` would not write the given chars to the expected position in
the original buffer.
This commit fixes that by writing to the `outBuffer.position()`, offset
by the current `DataBuffer.writePosition()`.
Fixes gh-22484
This commit introduces support for SpEL expressions for conditional
event processing in annotations such as @BeforeTestClass,
@BeforeTestMethod, etc.
This commit also introduces a new getTestContext() method in
TestContextEvent in order to improve the readability of such SpEL
expressions.
See gh-18490
This commit introduces a new EventPublishingTestExecutionListener for
publishing events to the test ApplicationContext. These may be consumed
by @EventListener annotated methods to react to the TestContext
lifecycle. The listener is not registered by default.
Closes gh-18490
Many Java 11 internal classes are located in the jdk package. ShadowingClassLoader should not load them, because it can cause errors, e.g. java.lang.IllegalAccessError: class jdk.internal.reflect.ConstructorAccessorImpl loaded by org.springframework.instrument.classloading.ShadowingClassLoader @2bea5ab4 cannot access jdk/internal/reflect superclass jdk.internal.reflect.MagicAccessorImpl
This commit moves mavenLocal() to the bottom of the repositories list
so that Gradle's Eclipse IDE support will properly link binary JARs to
their source JARS in generated Eclipse .classpath files.
According to Gradle experts, "`mavenLocal` should basically never be
the first repo in the list."
https://github.com/eclipse/buildship/issues/655#issuecomment-366227296
This commit adds a tip clarifying that TestNG's @BeforeClass and
@BeforeSuite methods can not be annotated with Spring's @Transactional
annotation.
Closes: gh-456
Prior to this commit, the negotiated content-type during the request
mapping phase would be kept as the response content-type header; this
information is used when rendering the error response and prevents a new
round of content negotiation to choose the media type that fits best.
This commit removes the response content type information at the
beginning of the error handling phase.
Fixes gh-22452
This commit is the first part of a more complete Coroutines
support coming in Spring Framework 5.2. It introduces suspendable
Kotlin extensions for Mono based methods in WebFlux classes like
WebClient, ServerRequest, ServerResponse as well as a Coroutines
router usable via `coRouter { }`.
Coroutines extensions use `await` prefix or `AndAwait` suffix,
and most are using names close to their Reactive counterparts,
except `exchange` in `WebClient.RequestHeadersSpec`
which translates to `awaitResponse`.
Upcoming expected changes are:
- Leverage `Dispatchers.Unconfined` (Kotlin/kotlinx.coroutines#972)
- Expose extensions for `Flux` based API (Kotlin/kotlinx.coroutines#254)
- Introduce interop with `CoroutineContext` (Kotlin/kotlinx.coroutines#284)
- Support Coroutines in `ReactiveAdapterRegistry`
- Support Coroutines for WebFlux annotated controllers
- Fix return type of Kotlin suspending functions (gh-21058)
See gh-19975
Prior to this commit, the `ExchangeFilterFunction` instances configured
on a `WebClient` instance would be executed as soon as the `exchange`
method would be called. This behavior is not consistent with the server
side and can confuse filter developers as they'd need to manually
`Mono.defer()` their implementations if they want to record metrics.
This commit defers all `ExchangeFilterFunction` processing at
subscription time.
Fixes gh-22375
This class is only known to be used in spring-data-jdbc-ext project
which was never upgraded to Spring Framework 5.x and is no longer
actively developed.
Closes gh-22402
This class is only known to be used in spring-data-jdbc-ext project
which was never upgraded to Spring Framework 5.x and is no longer
actively developed.
Closes gh-11647
* Test for multi-line comment block where the comment end delimiter occurs on a line starting with the single-line comment prefix
* ScriptUtils successfully parses a SQL script containing a multi-line comment block where the comment-end delimiter occurs on a line starting with the single-line comment prefix.
* Add integration tests for SpringBeanContainer (Hibernate ORM integration)
* Autowire bean properties of beans retrieved by name in SpringBeanContainer
* Add integration tests for fallback cases in SpringBeanContainer (Hibernate ORM integration)
* Fix SpringBeanContainer incorrectly losing the bean name when calling the fallback producer
(cherry picked from commit 00855c4f5f)
* Add integration tests for SpringBeanContainer (Hibernate ORM integration)
* Autowire bean properties of beans retrieved by name in SpringBeanContainer
* Add integration tests for fallback cases in SpringBeanContainer (Hibernate ORM integration)
* Fix SpringBeanContainer incorrectly losing the bean name when calling the fallback producer
Prior to this commit, calls to `MimeType` and `MediaType` would create a
significant amount of garbage:
* during startup time, in the static sections of `MimeType` and
`MediaType` when creating well-known types
* at runtime, when parsing media types for content negotiation or
writing known media types as strings in HTTP response headers
This commit does the following:
* Avoid parsing the well-known types and use regular constructors
instead
* Cache types in a simple LRU cache once they've been parsed, since an
application is likely to deal with a limited set of types
* Avoid using `java.util.stream.Stream` in hot code paths
Benchmarks show that a complete revision of the `MimeTypeUtils` parser
is not required, since the LRU cache is enough there.
Closes gh-22340
Prior to this commit, profiling sessions would show that using
`java.util.stream.Stream` in some hot code paths creates significant
garbage.
Where streams aren't really required, this commit turns those snippets
into imperative logic because those are likely to be called once or
multiple times per request.
Closes gh-22341
* pr/22337:
Polish "Fix use CompletableFuture in DeferredResultReturnValueHandlerTest"
Fix use CompletableFuture in DeferredResultReturnValueHandlerTest
This commit improves the message for HttpStatusCodeException so that it
defaults to the HttpStatus reason phrase if a status text is not
provided.
This commit also fixes SimpleClientHttpResponse so that it does not
return null for getStatusText().
Fixed#22162
Prior to this commit, Spring WebFlux function would let
`DecodingException` thrown by codecs bubble up to the web handler level.
Since this exception is not handled by default there, the response would
be turned into a HTTP 500 status.
In the annotation model, `ArgumentResolver` implementations wrap this
exception with a `ServerWebInputException`, which itself extends
`ResponseStatusException`. The latter is supported by the error handling
infrastructure as a HTTP 400 response.
This commit ensures that `DecodingException` instances are properly
wrapped in `ServerWebInputException` at the `ServerRequest` level
directly, thus supporting all setup modes ("standalone" and through the
`DispatcherHandler`).
Fixes#22290
Prior to this commit, `DataBuffer.write` would throw an
`IllegalStateException` when called with an empty `String`, since the
`CharsetEncoder` would be flushed on an incorrent state.
This commit skips entirely the encoding phase for empty `String`.
Fixes#22262
This commit removes the custom static resources for the reference
documentation and instead uses the new Spring Doc Resources project
https://github.com/spring-io/spring-doc-resources
The asciidoctor theme is now shared between Spring projects and
integrated in the project build.
This allows for proper nested type conversion in @Value Optional fields analogous to method parameters, through a new TypeDescriptor-based method in the TypeConverter SPI. As an additional and less involved measure that is worth backporting, DefaultListableBeanFactory defensively checks for pre-converted Optional wrappers.
Issue: SPR-17607
Commit #93b7a4 added support for pre-configuring URI variables at the
UriComponentsBuilder level, and also changed toUriString to encode
template and URI variables separately. However this went a bit too far
causing side effects for URLs with curly braces that don't represent
URI variables.
This commit restores the original toUriString behavior which is to
encode template and URI variables sepraately only if URI variables have
been pre-configured.
Issue: SPR-17630
The xml parser does not fill in defaults provided in the XSD when
validation is disabled. As a result, attributes like default-lazy-init
will not receive the value "default" but an empty string.
With this commit, BeanDefinitionParserDelegate now takes this into
account, checking default values against empty string as well as
"default".
As a consequence, default-lazy-init attribute should now work correctly
even when the XSD validation is disabled.
Issue: SPR-8335
Reactor is now building its Javadoc with a recent JDK version, which
changes the structure of the published HTML pages.
Without this change, the build fails during the Dokka generation with
the following exception:
```
Exception while loading package-list from
ExternalDocumentationLinkImpl(
url=http://projectreactor.io/docs/core/release/api/,
packageListUrl=http://projectreactor.io/docs/core/release/api/package-list)
```
This commit now points to the `/element-list` page, which seems to
contain the same information as the `package-list` page.
Aalto's InputFactoryImpl already disables loading of external entities
by default (property "javax.xml.stream.isSupportingExternalEntities").
This commit goes further by applying the same defensive measures as we
do elsewhere for XMLInputFactory, which disables DTD completely.
Arguably there is no good reason to enable that by default in WebFlux.
Typically a straight up equals as well as Collections#contains
checks for MediaType.ALL is susceptible to the presence of
media type parameters.
This commits adds equalsTypeAndSubtype as well as an
isPresentIn(Collection<MimeType>) methods to MimeType to faciliate
with checks for MediaType.ALL.
Issue: SPR-17550
Prior to this commit, one could write a `CharSequence` to an existing
`DataBuffer` instance by turning it into a byte array or `ByteBuffer`
first. This had the following disadvantages:
1. Memory allocation was not efficient (not leveraging pooled memory
when available)
2. Dealing with `CharsetEncoder` is not always easy
3. `DataBuffer` implementations, like `NettyDataBuffer` can use
optimized implementations in some cases
This commit adds a new `DataBuffer#write(CharSequence, Charset)` method
for those cases and also an `ensureCapacity` method useful for checking
that the current buffer has enough capacity to write to it..
Issue: SPR-17558
This commit makes TomcatServerHttpRequest aware of
HttpServletRequestWrappers, and TomcatServerHttpResponse aware of
HttpServletResponseWrappers.
Issue: SPR-17611
Commit #c187cb2 introduced proactive rejection of multiple subscribers
in ReactorClientHttpResponse, instead of hanging indefinitely as per
https://github.com/reactor/reactor-netty/issues/503.
However FluxReceive also rejects subsequent subscribers if the response
is consumed fully, as opposed to being canceled, e.g. as with
bodyToMono(Void.class). In that case, a subsequent subscriber causes
two competing error signals to be sent, and one gets dropped and
logged by reactor-core.
This fix ensures that a rejection is raised in
ReactorClientHttpResponse only after a cancel() was detected.
Issue: SPR-17564
Response status 415 (unsupported media type) reported as of 416 (which is Range Not Satisfiable), mismatching with superclass constructor parameter HttpStatus.UNSUPPORTED_MEDIA_TYPE
Prior to this change, ResourceUrlEncodingFilter would try to resolve
the resource path using request URL without removing fragment first,
whereas only paths should be used.
This commit synchronizes behavior of ResourceUrlEncodingFilter with
behavior of ResourceUrlProvider.
Issue: SPR-17535
Prior to this commit, parallel invocations of
MethodParameter.findParameterIndex() (invoked indirectly via
SynthesizingMethodParameter.forParameter() and
MethodParameter.forParameter()) could intermittently lead to an
IllegalArgumentException being thrown due to a race condition in the
internal implementation of the JDK's
java.lang.reflect.Executable.getParameters() method.
This commit addresses this issue by introducing a fallback for-loop
that iterates over the candidate parameters a second time using
equality checks instead of identity checks.
Issue: SPR-17534
Prior to this commit, parallel execution of @BeforeEach and @AfterEach
methods that accepted @Autowired arguments would fail intermittently
due to a race condition in the internal implementation of the JDK's
java.lang.reflect.Executable.getParameters() method.
This commit addresses this issue by creating instances of
SynthesizingMethodParameter via
SynthesizingMethodParameter.forExecutable(Executable, int) instead of
SynthesizingMethodParameter.forParameter(Parameter), since the latter
looks up the parameter index by iterating over the array returned by
Executable.getParameters() (which is not thread-safe).
Issue: SPR-17533
This commit introduces a new readMessageSize(DataBuffer input) private
method, inspired from CodedInputStream#readRawVarint32(int, InputStream)
and adapted for DataBuffer using MessageDecoderFunction fields in
order to support use cases where the message size is split between
distinct chunks.
It also fixes handling of end of streams by using
DataBuffer#readableByteCount instead of -1 which is only relevant with
InputStream.
Issue: SPR-17429
Prior to this commit, when errors happened before the response was
committed, the `Content-Length` response header would be left as is.
This can be problematic since the error can be handled later in the
chain and the response body changed accordingly. For example, Spring
Boot renders error pages in those cases. If the `Content-Length` is set,
HTTP clients can get confused and only consider part of the error
response body.
This commit ensures that any `Content-Length` response header is removed
in case of errors, if the response is not already committed.
This is done at the `AbstractServerHttpResponse` level, since errors can
be handled in multiple places and the response itself is the safest
place to handle this case.
As a consequence, this commit also removes `Content-Length` checks in
`EncoderHttpMessageWriter` since we now consider that we should rely on
the response body we're about to write rather than any previously set
value.
Issue: SPR-17502
Update the ServerHttpRespnose contract to indicate that server specific
sub-classes should fall back on the default status, if a status code
has not been set explicitly.
Issue: SPR-17368
This commit reverts the first optimizations listed in
fa096dc60f, as the default delimiters
do vary, namely by the charset given in the message mime type.
The mimetype charset might not be compatible with ASCII (i.e. anything
but UTF-8 or ISO-8859-1, for instance it might be UTF-16), and will not
successfully find the default delimiters as a consequence.
Added test to indicate the bug.
This CGLIB upgrade literally does not make any difference to Spring users since its only purpose is a default ASM7 declaration in its AsmApi class (which we patched a month ago). We nevertheless leave our local AsmApi copy in place for the time being, allowing for an individual upgrade of the declared ASM API version in the future.
Issue: SPR-17267
Issue: SPR-17371
After the fix #658c7f for lenient parsing of dates, the error message
raised uses an HttpHeaders-formatted date. As a result the test
verifying the error message fails in the beginning of the month between
1-9 because it's formatted slightly differently.
This commit makes the 3 existing InvocableHandlerMethod types more
consistent and comparable with each other.
1. Use of consistent method names and method order.
2. Consistent error formatting.
3. Explicit for loops for resolving argument values in webflux variant
because that makes it more readable, creates less garabage, and it's
the only way to bring consistency since the other two variants cannot
throw exceptions inside Optional lambdas (vs webflux variant which can
wrap it in a Mono).
4. Use package private HandlerMethodArgumentComposite in webflux
variant in order to pick up the resolver argument caching that the
other two variants have.
5. Polish tests.
6. Add missing tests for messaging variant.
1. Avoid re-creating the List with delimited byte arrays on every
request if using the default delimiters which don't vary by charset.
2. Replace flatMap with flatMapIterable for splitOnDelimiter.
3. Avoid going through DataBufferUtils#join, and unnecessarily creating
Flux from the List, since the join method needs a list anyway.
Prior to this commit, no `ResourceUrlProvider` was configured
in WebFlux (no bean was contributed by the WebFlux infrastructure).
Also, several `ResourceTransformer` instances that extend the
`ResourceTransformerSupport` base class need a `ResourceUrlProvider`
to resolve absolute URLs when rewriting resource URLs. At this point,
no `ResourceUrlProvider` was configured and they could only resolve
relative URLs.
This commit contributes a new `ResourceUrlProvider` to the WebFlux
configuration; this bean can be reused by the WebFlux infrastructure and
application code.
This also automatically configure this shared `ResourceUrlProvider`
instance on the resource chain where needed.
Issue: SPR-17433
Prior to this commit, `ResourceTransformerSupport.toAbsolutePath`
would call `StringUtils.applyRelativePath` in all cases. But this
implementation is prepending the given path even if the relative path
starts with `"/"`.
This commit skips the entire operation if the given path is absolute,
i.e. it starts with `"/"`.
Issue: SPR-17432
This commit fixes a memory leak in ServerSentEventHttpMessageWriter
that occurs when the input stream contains an error. Test added as well.
Issue: SPR-17419
Prior to this commit, the `ResourceUrlEncodingFilter` would wrap the
response and keep a reference to the request. When
`HttpServletResponse.encodeURL` is later called during view rendering,
the filter looks at the request and extracts context mapping information
in order to resolve resource paths in views.
This approach is flawed, when the filter is used with JSPs - if the
request is forwarded to the container by the `InternalResourceView`,
the request information is overwritten by the container. When the view
is being rendered, the information available in the request is outdated
and does not allow to correctly compute that context mapping
information.
This commit ensures that that information is being extracted from the
request as soon as the `ResourceUrlProvider` is set as a request
attribute.
Issue: SPR-17421
Fix ResourceRegionEncoder so that it checks for resource existance
before writing boundaries. Also defer data buffer allocation until
necessary.
Issue: SPR-17419
The fix for SPR-17178 switched from debug to warn level warning for
all sub-classes of AbstractHandlerExceptionResolver where the request
concerned the DefaultHandlerExceptionResolver only.
This commit restores the original DEBUG level logging that was in
AbstractHandlerExceptionResolver from before SPR-17178. In addition
DefaultHandlerExceptionResolver registers a warnLogCategory by default
which enables warn logging and hence fulfilling the original goal
for SPR-17178.
Issue: SPR-17383
This reverts commit 162112.
Instead we'll go for a bigger rollback of the change from SPR-17178 so
that only DefaultHandlerExceptionResolver does warn logging by default.
Issue: SPR-17388
Review and update Servlet and Undertow adapters to release any data
buffers they be holding on to at the time of error or cancellation.
Also remove onDiscard hooks from Reactor and Undertow request body.
For Reactor we expect it to be handled. For Undertow there isn't
any Reactor Core upstream for the callback to be useful.
Issue: SPR-17410
This commit changes the attributes stored under
RouterFunctions.MATCHING_PATTERN_ATTRIBUTE and
HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE from a String to a
PathPattern, similar to what annotated controllers set.
Issue: SPR-17395
This commit harmonizes the `HeadersAdapter` implementations across all
supported servers with regards to the `get(Object key)` contract; some
server implementations are not sticking to a `Map`-like contract and
return empty `List` instead of `null` when a header is not present.
This also fixes the `size()` implementations to reflect the number of
header keys, as some implementations consider multiple values for the
same header as different entries.
Issue: SPR-17396
As discussed in KT-25165, from a Kotlin POV enum constructors
have no parameter, this is an "implementation detail"
required for running on the JVM, so it seems relevant to skip
Kotlin reflection in that case and just delegate to Java
reflection.
Issue: SPR-16931
Tomcat and Jetty integration tests were moved out of spring-messaging
a very long time ago (before 4.0), but the dependencies remained
unnoticed until now.
Rather than formatting the expected value, and be susceptible to
minor formatting differences (e.g. 01 vs 1 for day of month), parse the
actual header value leniently with HttpHeaders and compare time values.
Issue: SPR-17330
If the content has not been consumed, cause it to be produced, and
wait for a certain amount of time before giving up, so the raw content
can be made available. This can occur when:
1) In a mock server scenario the Flux representing the client request
content is passed directly to the mock server request, but is never
consumed because of an error before the body is read.
2) Test obtains FluxExchangeResult (e.g. for streaming) but instead of
consuming the Flux, it calls getResponseBodyContent() instead.
Issue: SPR-17363
This commit adds special processing of some HTTP response headers in
Jetty and Tomcat; they both consider some headers like "Content-Length"
as specific and require explicit calls on the `HttpServletResponse`
itself on top of setting the HTTP response header.
Issue: SPR-17250
This commit avoids copying HTTP headers when mutating an HTTP request.
Instead, we're now unwrapping the `ReadOnlyHttpHeaders` (which is most
likely backed by the native request headers).
Issue: SPR-17250
Several benchmarks underlined a few hotspots for CPU and GC pressure in
the Spring Framework codebase:
1. `org.springframework.util.MimeType.<init>(String, String, Map)`
2. `org.springframework.util.LinkedCaseInsensitiveMap.convertKey(String)`
Both are linked with HTTP request headers parsing and response headers
writin during the exchange processing phase.
1) is linked to repeated calls to `HttpHeaders.getContentType`
within a single request handling. The media type parsing operation
is expensive and the result doesn't change between calls, since
the request headers are immutable at that point.
This commit improves this by caching the parsed `MediaType` for the
`"Content-Type"` request header in the `ReadOnlyHttpHeaders` class.
This change is available for both Spring MVC and Spring WebFlux.
2) is linked to insertions/lookups in the `LinkedCaseInsensitiveMap`,
which is the data structure behind `HttpHeaders`.
Those operations are creating a lot of garbage (including a lot of
`String` created by `toLowerCase`). We could choose a more efficient
data structure for storing HTTP headers data.
As a first step, this commit is focusing on Spring WebFlux and
introduces `MultiValueMap` implementations mapped by native HTTP headers
for the following servers: Tomcat, Jetty, Netty and Undertow.
Such implementations avoid unnecessary copying of the headers
and leverages as much as possible optimized operations provided by the
native implementations.
This change has a few consequences:
* `HttpHeaders` can now wrap a `MultiValueMap` directly
* The default constructor of `HttpHeaders` is still backed by a
`LinkedCaseInsensitiveMap`
* The HTTP request headers for the websocket HTTP handshake now need to
be cloned, because native headers are likely to be pooled/recycled by
the server implementation, hence gone when the initial HTTP exchange is
done
Issue: SPR-17250
Previously, if a DeferredImportSelector was identified at a later stage
as part of processing the collected set of deferred imports, such
selector was processed as a regular import selector.
Semantically, it makes sense as we already are in the deferred phase at
this point and it doesn't make much sense to bother about the extra
contract.
However, Spring Framework 5 introduced the notion of Group that a
deferred import selector can define. When it does, the container has to
honour the contract of the Group rather than calling the simpler
ImportSelector parent contract.
This commit restructures the processing of such case. When a deferred
import selector is detected while processing deferred import selectors,
a group is created with only that selector and the group API is invoked.
Issue: SPR-17351
Includes use of Files.getLastModifiedTime for NIO Paths, preservation of NIO-based resolution on createRelative, deprecation of PathResource, and consistent use of getContentLengthLong over getContentLength.
Issue: SPR-17320
This was a package private class in spring-messaging since 5.0, and was
recently made public in 5.1. This commit promotes it to spring-core
where it belongs next to all other ListenableFuture support classes.
Follow-up refactoring for SPR-17336
Collapse the package private AbstractMonoToListenableFutureAdapter into
its only sub-class MonoToListenableFutureAdapter. There is no need for
such an abstract class that makes it possible to adapt from one source
to a different target type. That's already covered by
ListenableFutureAdapter.
Follow-up refactoring for SPR-17336.
Spring Framework 5.1.0 exposed by mistake context in the Kotlin bean DSL
API in order to fix SPR-16269. Now that BeanFactory#getBeanprovider is
available, it should be exposed via a provider<Foo>() function in order
to provide a more clean API instead.
Issue: SPR-17352
Headings are optimized for how they appear in the left-hand side
navitation menu, with context provided by parent headings, and not
necessarily for how they read on their own.
At 2nd and 3rd level of nesting, which is where most headings are,
the wrapping becomes too distracting and the left-hand side navigation
sprawling.
Previously, both nullsLow(Comparator<T>) and
nullsHigh(Comparator<T>) returned a
NullSafeComparator which treated nulls as being
high. This commit corrects this typo.
Prefix the opening brace with a single space in some classes.
Replace tab character with space in javadoc of AttributeAccessor.
Also fix some other trivial formatting errors.
Closes gh-1979
In order to be able to leverage WebFlux configuration in a functional
way, WebHttpHandlerBuilder and RouterFunctionMapping should leverage
new ObjectProvider capabilities to get a sorted list of beans by type
instead of using autowired containers.
Issue: SPR-17327
Switch to using the sendClose method available since Reactor Netty 0.8
vs explicitly sending a CloseWebSocketFrame.
Related to SPR-17306, but does not address the root cause.
Fix some syntax errors and typos
* Fix syntax error in core-aop docs which caused incorrect document
generation
* Surround @Pointcut values with quotation marks
* Replace 'I' with 'you' in the 'In the XML style I can declare the
first two pointcuts' sentence
* Fix compileror typo
* Remove redundant parenthesis
* Remove redundant commas
* Add 'can' to the 'You configure additional aspects in similar fashion'
sentence
* Replace 'You can annotation any method' with 'You can annotate any
method'
* Add space to 'non-recoverablepersistence'
* Replace 'we shows' with 'we show'
* Fix 'java.utils.Map' typo
* Add space to 'byusing'
* Add space to '`Lifecycle`by'
* Replace 'You cN' with 'You can'
* Replace 'encourag' with 'encourage'
I edited for spelling, puncutation, grammar, usage, and corporate voice. I also added a bunch of cross-references and links to the Javadoc.
I also corrected the rendering problems that I had accidentally created in previous commits (because I was adjusting headings and adding callouts to listings.
Since non-default constructors are now evaluated for autowiring,
there is no need anymore for setting autowiring mode or exposing
it in Kotlin bean DSL.
Issue: SPR-17292
Support for Kotlin primary constructor and non-default public constructors in addition to default instantiation, aligned with AnnotationConfigApplicationContext and model attribute processing.
Issue: SPR-17292
Declaring beanPostProcessors (and also embeddedValueResolvers) as CopyOnWriteArrayList prevents ConcurrentModificationExceptions in case of concurrent registration/access attempts.
Issue: SPR-17286
1. Helper method to eliminate duplication in formatting (de-)serialized
values for logging introduced with prior commit #e62298.
2. Helper method for TRACE vs DEBUG logging with different details.
Issue: SPR-17254
At DEBUG show up to 100 chars, at TRACE show full formatted value.
Note that the formatValue helper method is duplicated a number of times
in this commit. A utility method will likely be added in spring-core
through an extra commit.
Issue: SPR-17254
This commit makes sure that in DataBufferUtils.write, any received data
buffers are returned as part of the returned flux, even when an error
occurs or is received.
Issue: SPR-16782
Before this commit, Kotlin inner class nested configuration
handling thrown an IndexOutOfBoundsException due to bogus filtering
of its constructor parameter reference to an instance of the outer
class.
This commit keep constructor parameter of type INSTANCE in order to
throw a more meaningful NoSuchBeanDefinitionException.
Issue: SPR-17222
placeholders
Spring 4.3 introduced support for registering a default embedded value
resolver for the default environment, in case of none having been
registered through post-processors (like PropertyPlaceholderConfigurer
and PropertySourcesPlaceholderConfigurer. However, the existing
documentation – stating that a static
PropertySourcesPlaceholderConfigurer bean is required in order for
values coming from @PropertySource declarations to be honored – was not
updated to reflect the change.
This commit addresses this by updating the JavaDoc for @Configuration
and @PropertySource accordingly
Issue: SPR-17212
1. Rename globalResources to useGlobalResources.
2. Use of global resources is mutually exlusive with explicit config.
3. Allow Consumer<HttpResources> to configure global resources.
4. Allow ConnectionProvider + LoopResources Supplier to customize
creation and initialization.
5. Do not manage externally provided ConnectionProvider + LoopResources
instances.
Issue: SPR-17243
This commit adds decoder/message-reader tests for errors in
the source data buffer publisher. Because the tests extend
AbstractDataBufferAllocatingTestCase, they also check whether
the buffers that precede the error in the stream are properly
released.
Issue: SPR-17025
This commit optimizes Flux <-> Mono conversions in our codebase by
avoiding to hide that conversion from Reactor.
This tries to keep conversions sequentially so that they can be detected
by Reactor and optimized. In Spring WebFlux, this means keeping the
conversions at the edges of a method implementation (right when getting
an input parameter, and before returning it as a result). If those
conversions are made between other operators, Reactor might not be able
to detect those conversions and optimize them.
Issue: SPR-17203
This commit introduces a dependency on the Awaitility assertion
framework and makes use of asynchronous assertions in order to make
tests for asynchronous events more robust.
Issue: SPR-17211
Aligned with HibernateJpaDialect, using ConnectionHandle as functional interface now. Also, LazyConnectionDataSourceProxy supports Connection holdability as applied by HibernateTransactionManager, for use with prepareConnection=true.
Issue: SPR-17216
Prior to this commit, an bug introduced in SPR-16949 prevented
`Mono.empty` bodies from being written to the response.
This commit ensures that empty bodies still trigger the writing to the
response and does not hang the processing of the exchange.
Issue: SPR-17220
This commit represents a best effort attempt at fixing remaining
"a" vs. "an" grammatical errors related links specified via a fully
qualified class name.
Issue: SPR-17208
When used as global Netty resources, ReactorResourceFactory creates and
sets those resources on Reactor's HttpResources directly.
When that ReactorResourceFactory bean is destroyed, those resources are
disposed but HttpResources still holds a reference to those and may try
to use them again.
This commit uses HttpResources to clear those resources and its
references to it, when the ReactorResourceFactory is treating those as
global.
Issue: SPR-17199
JettyResourceFactory, similar to ReactorResourceFactory, allows
to share resources (Executor, ByteBufferPool, Scheduler) between
Jetty clients and servers.
Issue: SPR-17179
Prior to this commit, when using the `SimpleClientHttpRequestFactory`
as a driver for `RestTemplate`, the HTTP response body would only be
drained if there was an attempt to read it in the first place.
This commit ensures that, even if there's no attempt at reading the
response body, it is properly drained when the response is closed to
make sure that the connection is released in a proper state and can be
put back in the connection pool for reuse.
Issue: SPR-17181
When dealing with `Optional` values in a Controller handler (for
example, values coming from a Spring Data repository), developers might
reuse this code snippet quite often:
```
@GetMapping("/user")
public ResponseEntity<Optional<User>> fetchUser() {
Optional<User> user = //...
return user.map(ResponseEntity::ok).orElse(notFound().build());
}
```
This commit adds a new static method on `ResponseEntity` for that,
simplifying the previous snippet with `return ResponseEntity.of(user);`
Note that in case more specific HTTP response headers are required by
the application, developers should use other static methods to
explicitly tell which headers should be used in each case.
Issue: SPR-17187
Includes caching of declared annotation arrays and combined searching for several annotation types (used in SpringCacheAnnotationParser).
Issue: SPR-16933
Prior to this commit, if a test class was meta-annotated with multiple
@BootstrapWith declarations that registered different
TestContextBootstrapper implementations, such a configuration would
result in an IllegalStateException, and there was no way to override
this behavior.
This commit addresses this shortcoming by relaxing the explicit
TestContextBootstrapper resolution in BootstrapUtils so that a directly
present @BootstrapWith annotation will now override declarations of
@BootstrapWith that are meta-present. In other words, if @BootstrapWith
is used as a meta-annotation, it can be overridden directly on the test
class via an explicit, local declaration of @BootstrapWith.
Issue: SPR-17006
This commit handles "empty" cases for `ResponseEntity` controller
handler return types when wrapped with a `java.util.Optional` in Spring
MVC or a single `Publisher` like `Mono`.
Given the following example for Spring MVC:
```
@GetMapping("/user")
public Optional<ResponseEntity<User>> fetchUser() {
Optional<User> user = //...
return user.map(ResponseEntity::ok);
}
```
If the resulting `Optional` is empty, Spring MVC will infer a
`ResponseEntity` with an empty body and a 404 HTTP response status.
The same reasoning is applied to Spring WebFlux with Publisher types:
```
@GetMapping("/user")
public Mono<ResponseEntity<User>> fetchUser() {
Mono<User> user = //...
return user.map(ResponseEntity::ok);
}
```
This feature is only valid for `HttpEntity` return types and does not
apply to `@ResponseBody` controller handlers.
Issue: SPR-13281
Rename "Builder" sub-section to "Configuration" and move it in the
beginning before all others since it explains how to create a client
in the first place.
Update content on Reactor Netty connector based on the API in 0.8 and
specifically address Reactor Netty resources and lifecycle.
Issue: SPR-16963
Prior to this commit, ScriptUtils supported MySQL-style escapes ('\\')
when splitting a script into statements; however, MySQL-style escapes
were not supported when determining if a given script contained a
specified statement delimiter. This caused executeSqlScript() to
erroneously fallback to a newline as the statement separator in such
cases.
This commit fixes this issue by implementing the same check for
MySQL-style escapes in containsSqlScriptDelimiters() that was already
present in splitSqlScript().
Issue: SPR-17120
This commit enables the `-use` javadoc flag so that class usage pages
are included in the aggregated JavaDoc that is published to
https://docs.spring.io/spring-framework/docs/.
Issue: SPR-17173
No that JCacheCache extends AbstractValueAdaptingCache instead of
directly implementing Cache an import statement can be used in favor
of using the FQCN for the field and constructor arguments.
For consistency with AnnotationAsyncExecutionInterceptor (based on AnnotatedElementUtils.findMergedAnnotation) which is the main companion of AnnotationMatchingPointcut's checkInherited mode.
Issue: SPR-16933
This commit allows to specify a custom CorsConfigurationSource
in AbstractHandlerMapping (both Servlet and Reactive variants).
AbstractHandlerMapping#getCorsConfigurations method is now
deprecated.
Issue: SPR-17067
1. Update ExchangeFilterFunctions to delegate internally to
HttpHeaders.setBasicAuth(user, password).
2. Remove deprecation from
ExchangeFilterFunctions.basicAuthentication(String user, String password)
It is still useful as a filter to insert the header.
3. Update deprecation notes.
Issue: SPR-17099
Forwarded headers are now processed before ServerWebExchange is created
through ForwardedHeaderTransformer which has the same logic as the
ForwardedHeaderFilter but works on the request only.
ForwardedHeaderFilter is deprecated as of 5.1 but if registered it is
removed from the list of filters and ForwardedHeaderTransformer is used
instead.
Issue: SPR-17072
This revision considers any java/javax and org.springframework.lang annotations as not synthesizable upfront, checking not only in isSynthesizable but also at synthesizeAnnotation(Array) level.
Issue: SPR-16933
Empty Maps are preferably initialized without capacity (not initializing them at all or lazily initializing with default capacity when needed).
Issue: SPR-17105
This commit introduces Protobuf support in WebFlux via dedicated
codecs.
Flux<Message> are serialized/deserialized using delimited Protobuf
messages with the size of each message specified before the message
itself. In that case, a "delimited=true" parameter is added to the
content type.
Mono<Message> are expected to use regular Protobuf message
format (without the size prepended before the message).
Related HttpMessageReader/Writer are automatically registered when the
"com.google.protobuf:protobuf-java" library is detected in the classpath,
and can be customized easily if needed via CodecConfigurer, for example
to specify protocol extensions via the ExtensionRegistry based
constructors.
Both "application/x-protobuf" and "application/octet-stream" mime types
are supported.
Issue: SPR-15776
Prior to this commit, controller handlers (regular and exception
handlers as well) would not overwrite existing HTTP response headers on
the exchange. This would lead to situations where Content-Type values
set during the initial handling phase would not be overwritten when
handling an error later on.
This commit aligns the implementation of that result handler on the
Spring MVC one in that regard.
Issue: SPR-17082
1. Revise @SubscribeMapping to address common points of confusion.
2. Add ExecutorSubsribableChannel.
3. Split Events and Interception in two.
Issue: SPR-16950
In order to be consistent with SPR-15776, and since it does not
provide clear added value, this commit deprecates
ExtensionRegistryInitializer and uses ExtensionRegistry
parameter instead in ProtobufHttpMessageConverter and
ProtobufJsonFormatHttpMessageConverter constructors.
Issue: SPR-17081
Introduces getBeanProvider(Class) and getBeanProvider(ResolvableType), also narrowing getBean(String, Class) and isTypeMatch(String, Class) to a non-null Class argument and enriching NoUniqueBeanDefinitionException with a full ResolvableType. In addition, ObjectProvider supports iterable/stream access for collection-style resolution of multiple matching beans now, and collection injection falls back to an empty collection in a single-constructor case with non-null arguments.
Issue: SPR-17075
Issue: SPR-11419
Issue: SPR-15338
This commit adds support for single-value reactive types in
@MessageMapping by converting them using ReactiveAdapterRegistry
and MonoToListenableFutureAdapter.
MonoToListenableFutureAdapter previously package private and used only
in org.springframework.messaging.tcp.reactor has been moved to
org.springframework.messaging.support and made public in order to be
used by ReactiveReturnValueHandler as well.
Issue: SPR-16634
This commit ignores errors like TransformerFactoryConfigurationError
that can be thrown when instantiating SourceHttpMessageConverter on
platforms where no TransformerFactory implementation is available,
like when compiling/running as GraalVM native images.
Issue: SPR-17007
This commit includes an optimization of BeansUtils#instantiateClass
that favors Java reflection for default constructors before leveraging
Kotlin one for finding primary constructors and avoids Kotlin related
conditions when running in Java.
Issue: SPR-17069
This revision limits serializability of derived interfaces, superclasses and type parameters, optimizing for introspection performance instead.
Issue: SPR-17070
Adds XML-based assertions in
org.springframework.test.web.reactive.server.WebTestClient.BodyContentSpec
for asserting against the XML body as well as xPath,
similar to those assertions offered when using
MockMvcResultMatchers.xpath().
Issue: SPR-16741
Since SPR-15205, the `FormHttpMessageConverter` is adding a `charset`
directive to the `Content-Type` request header in order to help servers
understand which charset is being used to encode headers of each part.
As reported in SPR-17030 and others, some servers are not parsing
properly such header values and assume that `boundary` is the last
directive in the `Content-Type` header.
This commit reorders the charset information right before the boundary
declaration to get around those issues.
Issue: SPR-17030
Prior to this commit, the `DefaultClientResponse` implementation would
handle HTTP client cases where the server response body would need to be
consumed (pooled resources need to be released) and the body publisher
cancelled right away. This is done to avoid reading the whole response
body and returning the connection to the pool, now that this connection
cannot be reused.
This was done already when the `WebClient` is asked for a `Void` type
for the response body.
SPR-17054 brought a new case for that: whenever no message reader is
able to decode the response body, an `UnsupportedMediaTypeException`
error signal is sent. Prior to this commit, the response body would not
be consumed and cancelled for that case.
This commit refactors all those cases from the `DefaultClientResponse`
directly into the `BodyExtractors`, since most of the logic and
knowledge for that belongs there. We only need to only apply this
behavior when the HTTP client is involved, as the server does not want
this to happen.
Issue: SPR-17054
See Javadoc on UriComponentsBuilder#uriVariables for details.
This helps to prepare for SPR-17027 where the MvcUriComponentsBuilder
already does a partial expand but was forced to build UriComonents
and then create a new UriComponentsBuilder from it to continue. This
change makes it possible to stay with the same builder instance.
Issue: SPR-17027
After the latest changes, two small fixes in the clone method to copy
the encode flag, and in the encodeUriTemplate method to account for
possible null query params.
Improvements in the URI encoding section.
Issue: SPR-17039, SPR-17027
Provides a non-null guarantee for MethodMatcher's targetClass argument and strict separation between IntroductionAwareMethodMatcher and regular MethodMatcher, enabling DefaultAdvisorChainFactory to defer its IntroductionAdvisor determination until encountering an actual IntroductionAwareMethodMatcher (even behind union/intersection).
Issue: SPR-17068
Given "/{foo}" and "/a=42;c=b", previously that would be treated as a
sequence of matrix vars with an empty path variable. After the change
the path variable "foo" is "a=42".
This should be ok for backawards compatibility since it's unlikely for
anything to rely on an empty path variable.
Issue: SPR-11897
The HandlerMethodParameter arrangement uses an approach similar to ModelAttributeMethodProcessor's FieldAwareConstructorParameter, merging the local parameter annotations with interface-declared annotations.
Issue: SPR-11055
Leverage https://github.com/jetty-project/jetty-reactive-httpclient
to add support for Jetty in WebClient via JettyClientHttpConnector.
Implemented with buffer copy instead of optimized buffer wrapping
because the latter hangs since Callback#succeeded doesn't allow
releasing the buffer and requesting more data at different times
(required for Mono<DataBuffer> for example).
See https://github.com/eclipse/jetty.project/issues/2429.
Issue: SPR-15092
Prior to this commit, resolving an argument for a WebFlux controller
that's missing from the request and not required by the handler would
throw a NullPointerException in some cases.
This involves the conversion of the parameter (a `String` parameter type
might not trigger this behavior) and sending a `null` within a reactive
stream, which is illegal per the RS spec.
We now rely on a `Mono.justOrEmpty()` to handle those specific cases.
Issue: SPR-17050
Includes tests for parsing all available locales on the JVM, checking toString/toLanguageTag equality between parsed and original locale.
Issue: SPR-7598
Issue: SPR-16651
Like CookieLocaleResolver, LocaleChangeInterceptor parses both locale formats by default now. Since it does not need to render the locale, its languageTagCompliant property is not relevant anymore at all.
The parseLocale method in StringUtils validates the locale value now and turns an empty locale into null, compatible with parseLocaleString behavior and in particular aligned with web locale parsing needs.
Issue: SPR-16700
Issue: SPR-16651
Includes an extension of SmartValidator for candidate value validation, as well as nullability refinements in Validator and BindingResult.
Issue: SPR-16840
Issue: SPR-16841
Issue: SPR-16854
DefaultUriBuilderFactory now uses EncodingMode.TEMPLATE_AND_VALUES by
default. However the RestTemplate explicitly sets it to the previous
setting EncodingMode.URI_COMPONENTS, so this affects mainly the
WebClient and any direct use of DefaultUriBuilderFactory to configure
either the RestTemplate or the WebClient.
Issue: SPR-17039
The ability to request to encode before `build()`, and more importantly
before expanding, allows stricter encoding to be applied to URI vars
and consequently to neutralize the effect of characters with reserved
meaning in a URI.
Issue: SPR-17039
Introduces a configure method pattern for Supplier-style configuration and a common SingletonSupplier decorator for method reference suppliers. Also declares jcache.config and jcache.interceptor for non-null conventions.
Issue: SPR-17021
This commit removes the session threshold check added recently which
is not effective since maxIdleTime is usually much longer than the
frequency of checks. The lazy triggering of expiration checks during
create or retreive are simple and the most effective
This commit also adds a maxSessions limit on the total number of
sessions that can be created at any one time, a getSessions method
for management purposes, and a removeExpiredSessions public API
for manual triggering of expiration checks.
Issue: SPR-17020, SPR-16713
Prior to this commit, `WebClient` would throw `IllegalArgumentException`
when receiving an HTTP response with an unknown HTTP status code.
This commit is a follow up of SPR-16748 (supporting non-standard HTTP
status codes on the reactive `ClientHttpResponse`), and is mirroring
SPR-15978 (supporting non-standard HTTP status codes in `RestTemplate`).
With this change, `WebClient` now tolerates unknown status codes in some
cases, while not offering that choice as a first class citizen:
`HttpStatus` is still the preferred way to deal with HTTP status codes.
Here's how `WebClient` will behave when fetching the full response:
```
// Given a remote endpoint returning a "123" HTTP status code
Mono<ClientResponse> result = this.webClient.get()
.uri("/status/123")
.exchange();
// will still throw an IllegalArgumentException
HttpStatus status = result.block().statusCode();
// is safe and will return 123
int statusCode = result.block().rawStatusCode();
```
Resolving directly the response body with `retrieve()` is different.
```
// will send an error signal with a UnknownHttpStatusCodeException
Mono<String> result = this.webClient.get()
.uri("/status/123")
.retrieve()
.bodyToMono(String.class);
```
In general, `WebClient` will provide high-level support
for well-known HTTP status codes, like error handling with
`WebClient.ResponseSpec#onStatus`.
For such support with unknown status codes, it is better to rely
on lower level constructs such as `ExchangeFilterFunction`.
Issue: SPR-16819
1. Add session count threshold as am extra pre-condition.
2. Check pre-conditions for expiration checks on every request.
Effectively an upper bound on how many sessions can be created before
expiration checks are performed.
Issue: SPR-17020
This commit restricts the support of `"Content-Range"` when returning
`Resource` instances from Controllers - now only "HTTP 200 OK" responses
will be considered, as Controllers might want to handle content range
themselves.
Issue: SPR-16921
1. Use special category prefix "spring-web.reactivestreams" for logging
of reactive streams signals in spring-web, since those are quite
verbose would fill the logs at TRACE.
2. Add and use loggers in request and websocket session implementations
separate from reactive streams bridge for regular TRACE logging.
3. Improve log messages and add where missing (e.g. for Reactor)
Issue: SPR-16898
Hiding it (at AbstractServerHttpRequest) complicates matters since
requests are often mutated and decorated, plus it's also possible to
implement the interface directly (we've one, albeit corner case).
Issue: SPR-16966
1. Eliminate WebSocketClientSupport base class whose main value was
to provide logging but those methods get in the way of inserting a
log prefix.
2. Remove checks and synchronization in lifecycle methods of Jetty
client since underlying Jetty client already has that.
This involves a new ResourceTransactionDefinition variant that JpaTransactionManager indicates a transaction-local EntityManager on. HibernateJpaDialect uses this indicator for hard read-only behavior.
Issue: SPR-16956
LocalSessionFactoryBean automatically registers its containing BeanFactory as a BeanContainer when Hibernate 5.3 or higher is on the classpath.
Issue: SPR-16305
SessionHolder extends EntityManagerHolder now, allowing for @PersistenceContext and co to interact with HibernateTransactionManager's thread-bound transactions, and SpringSessionContext is capable of interacting with JpaTransactionManager by detecting a plain EntityManagerHolder as well.
Issue: SPR-17002
This commit introduces a test to verify that multiple declarations of
@BootstrapWith that register the same TestContextBootstrapper type
(i.e., duplicates) do not result in an error.
Issue: SPR-17006
After this change sameSite still gets a default value of "Strict" in
CookieWebSessionIdResolver but for changes to either sameSite or secure
it is now expected to use
addCookieInitializer(Consumer<ResponseCookie.ResponseCookieBuilder>).
Issue: SPR-16418, SPR-16980
In order to allow Spring Framework applications running as GraalVM
native images, ReactiveAdapterRegistry should perform explicit class
checks instead of catching Throwable in order to avoid
UnsupportedFeatureError errors.
Issue: SPR-17000
Includes specific fine-tuning of ProtobufHttpMessageConverter and JAXB2 based message converters, as well as revised javadoc for abstract base classes.
Issue: SPR-16995
Includes an efficient implementation of isEmpty(), not relying on a full entry count but rather backing out once a non-empty hash segment has been found.
Issue: SPR-16994
Includes a clarification of ThreadPoolExecutor configuration options and a note on early AsyncConfigurer initialization.
Issue: SPR-16944
Issue: SPR-16945
Allows for skipping the now-deprecated postProcessPropertyValues callback with its expensive PropertyDescriptor retrieval requirement. RequiredAnnotationBeanPostProcessor (which is dependent on postProcessPropertyValues) and the @Required annotation itself are also deprecated now: in favor of constructor injection (or afterPropertiesSet).
Issue: SPR-16918
This commit introduces RouterFunctions.Builder, a new way to build
router functions that does not require static imports, thus being more
discoverable and convenient.
Issue: SPR-16953
Polish a few issue identified when adding checkstyle to the
build. Although checkstyle is not enforcing rules on tests,
these are a few minor changes that are still worth making.
Issue: SPR-16968
Reorganize imports to ensure consistent ordering. This commit also
expands any `.*` static imports in favor of using fully-qualified
method references.
Issue: SPR-16968
Update all classes so that inner classes are always last. Also
ensure that utility classes are always final and have a private
constructor and make exceptions final whenever possible.
Issue: SPR-16968
Add checkstyle to the build to enforce Spring Framework coding
conventions. Rule suppressions are used for several classes where
relaxing the rules makes more sense than fixing them.
Issue: SPR-16968
In SPR-16892, the `EncoderHttpMessageWriter` has been improved to write
`"Content-Length"` HTTP response headers if the response body is of type
`Mono` (i.e. the actual content length is easily accessible without
buffering a possibly large response body). That change was relying on
the fact that the server side is using a `ChannelSendOperator` to delay
the writing of the body until the first signal is received.
This strategy is not effective on the client side, since no such channel
operator is used for `WebClient`. This commit improves
`EncoderHttpMessageWriter` and delays, for `Mono` HTTP message bodies
only, the writing of the body so that we can write the
`"Content-Length"` header information once we've got the body resolved.
Issue: SPR-16949
Allow the `Environment` to accept a generic `Profiles` interface which
can support more complex matching rules. The previous
`acceptsProfiles(String...)` method now uses `Profiles.of` which
supports basic profile expressions such as "(a | b) & !c"
Issue: SPR-12458
This commit adds support for the "SameSite" attribute in response
cookies. As explained in rfc6265bis, this attribute can be used to limit
the scope of a cookie so that it can't be attached to a request unless
it is sent from the "same-site".
This feature is currently supported by Google Chrome and Firefox, other
browsers will ignore this attribute.
This feature can help prevent CSRF attacks; this is why this commit adds
this attribute by default for SESSION Cookies in WebFlux.
See: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis
Issue: SPR-16418
Also, ZeroCopyHttpOutputMessage provides writeWith(Path, int, int), enforcing that variant as the implementation target in 5.1 (analogous to FilePart).
Issue: SPR-16925
@PathVariable's javadoc states that it supports MultiValueMap
parameters (introduced by commit df0902), but by reading through the
code, that does not seem to be the case (compare, e.g.,
PathVariableMapMethodArgumentResolver to
RequestParamMapMethodArgumentResolver).
Moreover, parsing MultipleValueMap is done according to the ";"
character, and placing such a character in a path (e.g., consider
something like "/app/{param}/show" would just break the path.
This patch fixes PathVariable's javadoc by removing the mention of
MultiValueMap.
This commit fixes the write checks for
`ResourceRegionHttpMessageConverter`, which was previously not checking
properly the parameterized type (e.g. in case of a `List<Something>`).
Issue: SPR-16932
This commit restricts the allowed HTTP methods on HiddenHttpMethodFilter
(Reactive variant) to the following: PUT, DELETE, PATCH.
This filter is meant to be used to simulate those methods from HTML
forms sent by browsers, so no other methods are allowed.
Issue: SPR-16836
This commit restricts the allowed HTTP methods on HiddenHttpMethodFilter
(Servlet variant) to the following: PUT, DELETE, PATCH.
This filter is meant to be used to simulate those methods from HTML
forms sent by browsers, so no other methods are allowed.
Issue: SPR-16836
Prior to this commit, the generated POMs for Spring Framework modules
would contain unneeded/harmful information from the Spring Framework
build:
1. The BOM imports applied to each module by the dependency
management plugin, for example for Netty or Reactor Netty.
Spring should not export that opinion to its POMs.
2. The exclusion of "org.slf4:jcl-over-slf4j" from *all* dependencies,
which made the POMs much larger than necessary and suggested to
developers that they should exclude it as well when using all those
listed dependencies. In fact, only Apache Tiles currently brings that
transitively.
This commit removes that information from the POMs.
The dependencyManagement Gradle plugin is disabled for POM generation
and we manually resolve the dependency versions during the generation
phase.
The Gradle build is streamlined to exclude "org.slf4:jcl-over-slf4j"
only when necessary.
Issue: SPR-16893
After the Groovy 2.5 upgrade, the Spring Framework build on JDK9 hit
GROOVY-8631. Adding the relevant `jax-api` dependency to the module
didn't fix this issue. The Groovy release notes mention the use of the
`--add-modules` JVM flag, but this is not an option for this build which
should run on JDK8 -> JDK11.
This commit changes the dependency from `groovy-all` to more focused
dependencies on Groovy in the `spring-beans` and `spring-context`
modules. This change seems to avoid the automatic loading of Groovy
enhancements to JAXB (shipped with `groovy-xml`).
See:
* http://groovy-lang.org/releasenotes/groovy-2.5.html#Groovy2.5releasenotes-Knownissues
* https://issues.apache.org/jira/browse/GROOVY-8631
Issue: SPR-15407
This commit adds FormContentFilter, which is the same as the
HttpPutFormContentFilter but also supports DELETE.
The HttpPutFormContentFilter is now deprecated.
Issue: SPR-16874
The key in CachingResourceResolver now includes the "Accept-Encoding"
request header cleaned to exclude "*", "identity", and parameters, and
also sorted alphabetically.
For encoded resources the response now includes a response header with
"Vary: Accept-Encoding".
Issue: SPR-16381
The new EncodedResourceResolver is a generalized version of
GzipResourceResolver that can be configured to support different
content codings, by "br" and "gzip".
GzipResourceResolver is now deprecated.
Issue: SPR-16381
This commit makes it possible to pass attributes from the WebSession of
a handshake request to the WebSocketSession, by configuring a
Predicate<String> on HandshakeWebSocketService.
Issue: SPR-16212
After the recent changes to expose configuring TcpOperations, it no
longer makes sense to automatically log the relayHost/Port since that's
mutually exclusive with a custom TcpOperations.
Instead we delegate to TcpOperations.toString().
Issue: SPR-16801
DefaultMultipartHttpServletRequest always returned mulitpart parameter
values only rather than aggregating with query parameters, which
contradicts with Servlet spec, section 3.1, and is inconsistent with
StandardMultipartHttpServletRequest.
Issue: SPR-16590
This commit removes all places where forwarded headers are checked
implicitly, on an ad-hoc basis.
ForwardedHeaderFilter is expected to be used instead providing
centralized control over using or discarding such headers.
Issue: SPR-16668
This commit exposes the resource lookup function used by
`RouterFunctions.resources(String, Resource)`, so that it can be
composed upon.
Issue: SPR-16788
This commit introduces support for creating a new `ServerRequest` from
an existing instance. This is especially useful when filtering requests
in a HandlerFilterFunction.
Issue: SPR-16707
Prior to this commit, a YAML entry that define an empty array value was
lost. This commit makes sure to flag it with an empty String, which
corresponds as an empty comma separated list of entries in the
properties format.
Issue: SPR-16769
With this commit, WebFlux server uses warning instead of error log level
for request handling, and also just print the message instead of the
stacktrace which is mostly meaningless in reactive world.
Complementary to this change, Reactor Netty removed additional logging
as part of https://github.com/reactor/reactor-netty/issues/339.
Issue: SPR-16688
1. Consistent with "xml code" examples.
2. "xml()" is a static method and will use default builder config,
so use createXmlMapper(true) instead.
3. Fix mvc namespace tag typo.
Prior to this commit, the `AbstractMessageConverterMethodProcessor`
would fail to convert `InputStreamResource` to `ResourceRegion` as
expected, since the content length cannot be read without consuming the
stream. This is enforced by the `HttpRange` class.
Now the method processor would still try to output HTTP range response
headers to provide range support information. This step is using the
resource content length and reads the input stream, leading to
exceptions such as "IllegalStateException: InputStream has already been
read".
This commit improves the return type detection and excludes early
`InputStreamResource` return types. With those types, HTTP range support
is now completely disabled.
Issue: SPR-16754
ServerSentEventHttpMessageReader had logic to split on new lines
and buffer until an empty new line (start of a new event). To account
for random data chunking, it later re-assembled the lines for each
event and split again on new lines. However bufferUntil was still
unreliable a chunk may contain nothing but a newline, which doesn't
necessarily mean an empty newline in the overall SSE stream.
This commit simplifies the above by delegating the splitting of the
stream along newlines to StringDecoder.
Issue: SPR-16744
Prior to this commit, due to KT-5464 type inference issue there was not
proper way to provide body expectations with WebTestClient. This commit
provides a workaround by updating the existing Kotlin extension to
return a Kotlin compatible API.
Issue: SPR-15692
Includes efficient check for same ClassLoader in ClassUtils.isVisible, efficient MethodMatchers check for IntroductionAwareMethodMatcher, and supertype method resolution in MethodMapTransactionAttributeSource.
Issue: SPR-16723
Prior to this commit, the various `HttpMessageConverter` instances
configured for a given `RestTemplate` instance could all contribute
`MediaType` values to the "Accept:" request header.
This could lead to duplicate media types in that request header,
cluttering for the HTTP request for no reason.
This commit ensures that only distinct values are added to the request.
Issue: SPR-16690
This commit introduces a deferred initialization of the declared beans
in order to make it possible to access to the environment (and even
to the context for advanced use-cases) in the beans { } Kotlin DSL.
Issues: SPR-16269, SPR-16412
HandlerMethodReturnValueHandlerComposite and
AbstractMethodMessageHandler iterate using index over collections
implementing RandomAccess to avoid unnecessary iterators.
Using the simple example shown in the ticket but switching from
Mono<String> to Flux<String> (and 5,000,000 onNext calls) shows that
constant pausing causes significant overhead and is not worth the
trouble vs ignoring the onWritePossible in REQUESTED state.
Issue: SPR-16702
Undertow does not provide a way to check if we can write so with the
current implementation of isWritePossible, deep recursion can occur
when writing slows down. We now use a flag to keep track of write
ChannelListener callbacks.
This commit also addresses a related issue in
AbstractListenerWriteProcessor that went undected since #3c2d186
where after a large (single) buffer that is not written fully, the
completion signal is processed before the all data is written.
Issue: SPR-16702
Includes direct use of ControllerMethodInvocationInterceptor for return type Object, avoiding the attempt to generate an Object subclass.
Issue: SPR-16710
Spring's CGLIB fork is patched with local copies of affected files here, introducing the notion of a "contextClass" (e.g. the proxy superclass) which gets passed through to ReflectUtils.defineClass for delegating to MethodHandles.Lookup.defineClass eventually, against a privateLookupIn(contextClass) lookup context on JDK 9/10/11.
Issue: SPR-15859
This commit documents the difference between configuring the socket
timeout on the `RequestConfig` and on the `SocketConfig`.
The first one does not affect timeouts when establishing an SSL
connection or sending a CONNECT request to a proxy. For these use cases,
it is required to configure `SocketConfig` on the `HttpClient` instance
directly.
Issue: SPR-16697
Gradle 4.6 provides built-in support for the JUnit Platform within the
standard `test` task.
This commit configures a custom `testJUnitJupiter` test task for
executing JUnit Jupiter tests directly on the JUnit Platform instead of
indirectly on JUnit 4 via @RunWith(JUnitPlatform.class).
This switch provides for better integration with Gradle's test reporting
and paves the way for a possible transition to the JUnit Platform in the
future.
Issue: SPR-16672
This commit specifies a local packageListUrl and defines that dokka task
must be executed after the api task in order to be able to build KDoc
during the release process when the Spring Framework's Javadoc is not
published yet.
Issue: SPR-16687
This breaks the package dependency cycle between web.server/web.method and makes ServerErrorException more generally applicable. Includes deprecation of the plain reason constructor variant, in favor of providing a Method or MethodParameter context (which MatrixVariableMethodArgumentResolver does now).
Prior to this commit it was impossible to have an individual
constructor argument in a @Nested (i.e., inner) test class injected via
@Autowired, @Qualifier, or @Value.
This is due to a bug in javac on JDK versions prior to 9, whereby
annotation lookups performed directly via the
java.lang.reflect.Parameter API fail for inner class constructors.
Specifically, the parameter annotations array in the compiled byte code
for the user's test class excludes an entry for the implicit enclosing
instance parameter for an inner class constructor.
This commit introduces a workaround in ParameterAutowireUtils for this
off-by-one error by transparently looking up annotations on the
preceding Parameter object (i.e., index - 1). In addition, this commit
relies on the change recently introduced in MethodParameter in order to
compensate for the same JDK bug (see SPR-16652).
Issue: SPR-16653
In my opinion, we should parse ":{x}" style parameter as "x" is parameter using "NamedParameterUtils.parseSqlStatement",
so the condition "j - i > 2" is the correct condition, not "j - i > 3", because if "i" is the index of
":" in ":{x}", and "j" is the index of "}" in ":{x}", "j - i == 3" is true.
Also add a test case for SPR-16663.
This commit introduces tests for looking up annotations on parameters
in constructors for nested and inner classes via Spring's
MethodParameter abstraction.
The test for an inner class is currently disabled since it fails on
JDK 8. See JIRA issue for details.
Issue: SPR-16652
Consistently return "*/*" if no media types were requested rather than
an empty list. Existing code has to check for both in any case to see
if nothing was requested.
Issue: SPR-16624
Consistently return "*/*" if no media types were requested rather than
an empty list. Existing code has to check for both in any case to see
if nothing was requested.
Issue: SPR-16624
This commit introduces @Nested tests to verify support for constructor
injection when using the SpringExtension.
One of the tests is disabled on Java 8 due to a bug in javac that was
first fixed in JDK 9.
See https://github.com/junit-team/junit5/issues/1345 for details.
The prevailing current wisdom is to use the default constructor for
secure and let it pick the best algorithm for the OS.
On Java 8 (Oracle), Linux this results in "NativePRNG" which uses
/dev/random (potentially blocking) for the initial seed, and
/dev/urandom (non-blocking) for subsequent calls to nextInt.
Issue: SPR-16635
Rather than create a new EvaluationContext instance per evaluation, we
now create a statically shared instance, without the root object in it,
and re-use it for all evalutations.
The web.server package is quite low-level and should not depend on web.bind in order to avoid a dependency cycle. Extracting the introspection of the ResponseStatus annotation into a WebFlux-level subclass resolves the cycle.
Issue: SPR-16567
Undertow does not provide a way to check if data is available to read
but instead we have to try to read and see if any data is returned.
This makes it impossible to implement checkOnDataAvailable without
trying to read and that can lead to infinite recursion like this:
...
UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156)
AbstractListenerReadPublisher.changeToDemandState(AbstractListenerReadPublisher.java:177)
AbstractListenerReadPublisher.access$900(AbstractListenerReadPublisher.java:47)
AbstractListenerReadPublisher$State$4.onDataAvailable(AbstractListenerReadPublisher.java:319)
AbstractListenerReadPublisher.onDataAvailable(AbstractListenerReadPublisher.java:85)
UndertowServerHttpRequest$RequestBodyPublisher.checkOnDataAvailable(UndertowServerHttpRequest.java:156)
This commit prevent the call to checkOnDataAvailable() when switching
states from READING->DEMAND which implies we exited the readAndPublish
loop because there was no more data to read.
Issue: SPR-16545
This commit allows several DeferredImportSelector instances to be
grouped and managed in a centralized fashion. This typically allows
different instances to provide a consistent ordered set of imports to
apply.
Issue: SPR-16589
This commit picks up where SPR-14498 left off by adding support for an
explicit target type when using JsonPath to perform an assertion against
the response content using a Hamcrest Matcher.
Specifically, there is a new overloaded value(Matcher<T>, Class<T>)
method in JsonPathResultMatchers for use with Hamcrest matchers where
the target type (i.e., Class<T>) can be specified.
Issue: SPR-16587
With this change the code generation for method and property
references is modified to include branching logic in the
case of null safe dereferencing (?.). This is complicated
by the possible usage of primitives on the left hand side
of the dereference. To cope with this case primitives are
promoted to boxed types when this situation occurs enabling
null to be passed as a possible result.
Issue: SPR-16489
This commit restructures the existing content to separate out Overview
content into its own section, and also introduces more formal structure
where reference type content can be expanded over time.
Issue: SPR-16547
Prior to this commit, the `HttpEntityMethodProcessor` would check HTTP
conditions on non-safe requests (i.e. not GET/HEAD). This would prevent
Controllers from returning `ResponseEntity` containing response headers
with updated values of `"Last-Modified"` or `ETag` once the resource has
been updated.
This commit avoids those checks for non GET/HEAD requests - this code
can still be leveraged from Controllers themselves using
`ServletWebRequest::checkNotModified` methods.
Issue: SPR-15780
After send error, ignore calls to complete or completeWithError by the
application in the same thread (e.g. try-catch block), to avoid a
competing with an error callback from servlet container during which
the same action is taken.
Issue: SPR-16548
When checking whether there is still request body the first method
that should be checked is ServletInputStream.isReady() and then
ServletInputStream.isFinished(). ServletInputStream.isReady() is the active
method whereas the ServletInputStream.isFinished() is not.
It is important to call ServletInputStream.isReady() because if it returns
false it will schedule a dispatch and if the request body is already read it will
send onAllDataRead event.
Issue: SPR-16521
Includes related polishing in core.metadata and datasource.embedded and a revision of the corresponding database definitions in sql-error-codes.
Issue: SPR-16558
This commit makes sure that no `StringIndexOutOfBoundsException` is
thrown when `getForRequestUrl` is called with a URL that's shorter than
the expected context path.
Issue: SPR-16526
Jackson2Tokenizer now also wraps JsonProcessingException's on
endOfInput(), as it also does in tokenize(DataBuffer). This ensures
treating those errors as 400 vs 500.
Issue: SPR-16521
When read returns -1, we know we've reached the end of input. Instead
of waiting for the onAllDataRead container callback, this commit
proactively calls onAllDataRead.
Issue: SPR-16521
@@ -7,8 +7,8 @@ First off, thank you for taking the time to contribute! :+1: :tada:
* [Code of Conduct](#code-of-conduct)
* [How to Contribute](#how-to-contribute)
* [Discuss](#discuss)
* [Create a Ticket](#create-a-ticket)
* [Ticket Lifecycle](#ticket-lifecycle)
* [Create an Issue](#create-an-issue)
* [Issue Lifecycle](#issue-lifecycle)
* [Submit a Pull Request](#submit-a-pull-request)
* [Build from Source](#build-from-source)
* [Source Code Style](#source-code-style)
@@ -24,70 +24,71 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
#### Discuss
If you have a question, check StackOverflow using
[this list of tags](https://spring.io/questions), organized by Spring project.
Find an existing discussion or start a new one if necessary.
If you have a question, check StackOverflow using
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest).
Find an existing discussion, or start a new one if necessary.
If you suspect an issue, perform a search in the
[JIRA issue tracker](https://jira.spring.io/browse/SPR), using a few different keywords.
When you find related issues and discussions, prior or current, it helps you to learn and
it helps us to make a decision.
If you believe there is an issue, search through
[existing issues](https://github.com/spring-projects/spring-framework/issues) trying a
few different ways to find discussions, past or current, that are related to the issue.
Reading those discussions helps you to learn about the issue, and helps us to make a
decision.
#### Create a Ticket
#### Create an Issue
Reporting an issue or making a feature request is a great way to contribute. Your feedback
and the conversations that result from it provide a continuous flow of ideas.
and the conversations that result from it provide a continuous flow of ideas. However,
before creating a ticket, please take the time to [discuss and research](#discuss) first.
Before you create a ticket, please take the time to [research first](#Discuss).
If creating an issue after a discussion on Stack Overflow, please provide a description
in the issue instead of simply referring to Stack Overflow. The issue tracker is an
important place of record for design discussions and should be self-sufficient.
If creating a ticket after a discussion on StackOverflow, please provide a self-sufficient description in the ticket, independent of the details on StackOverview. We understand this is extra work but the issue tracker is an important place of record for design discussions and decisions that can often be referenced long after the fix version, for example to revisit decisions, to understand the origin of a feature, and so on.
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework
# <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")
This is the home of the Spring Framework, the foundation for all
[Spring projects](https://spring.io/projects). Together the Spring Framework and the family of Spring projects make up what we call "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".
Spring provides everything you need beyond the Java language to create enterprise
applications in a wide range of scenarios and architectures. Please read the
section in the reference for a more complete introduction.
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
## Code of Conduct
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc).
By participating you are expected to uphold this code.
Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
This project is governed by the [Spring Code of Conduct](CODE_OF_CONDUCT.adoc). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Access to Binaries
For access to artifacts or a distribution zip, see the
For access to artifacts or a distribution zip, see the [Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts) wiki page.
## Documentation
The Spring Frameworks maintains reference documentation
([published](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and
[source](src/docs/asciidoc)),
Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## Micro-Benchmarks
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) Wiki page.
## Build from Source
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
wiki page and also [CONTRIBUTING.md](CONTRIBUTING.md).
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.
[@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](http://spring.io/blog/),
and releases are announced via our [news feed](http://spring.io/blog/category/news).
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).
## License
The Spring Framework is released under version 2.0 of the
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.
=== Setting up your development environment
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
You can then login with the instance using:
[source]
----
$ fly -t spring login -n spring-framework -c https://ci.spring.io
----
Once logged in, you should get something like:
[source]
----
$ fly ts
name url team expiry
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
----
=== 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
* `scripts/` holds the build scripts that ship within the CI container images
* `tasks` contains the task definitions used in the main `pipeline.yml`
=== 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:
// Replace classpath entries with project dependencies (GRADLE-1116)
// http://issues.gradle.org/browse/GRADLE-1116
// https://issues.gradle.org/browse/GRADLE-1116
eclipse.classpath.file.whenMerged{classpath->
defregexp=/.*?\/([^\/]+)\/build\/([^\/]+\/)+(?:main|test)/// only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Ensure that Eclipse launches with JDK 8.
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
1. Code away!
## Known Issues
1.`spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the build.
1.`spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
- If you installed _AJDT_ into Eclipse it should work.
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
the IDE.
- Resolving this is a work in progress.
- If attempting to run all JUnit tests from within the IDE, you may need to set the following VM options to avoid out of memory errors: `-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m`
## Tips
In any case, please do not check in your own generated `.classpath` file, `.project`
file, or `.settings` folder. You'll notice these files are already intentionally in
`.gitignore`. The same policy holds for IDEA metadata.
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.