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
Make the protected fields in AbstractJackson2Encoder private plus
minor refactoring to the way streaming separators are applied.
The current (5.0.3) behavior is to always use '\n', but in 5.0.4 the
newly supported "application/stream+x-jackson-smile" needs to be
excluded from that. For now, separator determination remains private
in the abstract base class, but current behavior remains which is to
apply '\n' by default.
Issue: SPR-15424
This commit adds an Asciidoc anchor to the section on different injection
styles to be able to link to the discussion as official recommendation.
Closes gh-1681
As of 4.3.13 MappingJackson2MessageConverter uses the MethodParameter
hint to obtain generic type information but it needs to be careful, and
nest one level, if the target parameter type has a Message wrapper.
Issue: SPR-16486
This commit introduces DataBuffer.asInputStream(boolean), that can
release the underlying buffer when the stream is closed.
Furthermore, this commit adds additional javadoc.
Issue: SPR-16444
After this commit the use of interval in tests is combined with
take(n).onBackpressureBuffer(n) to ensure emissions don't fail if the
fixed rate is exceeded (e.g. on slow CI server).
Tests that verify N number of items followed by verifyOnComplete()
should set the number of emissions to N.
Tests that verify N number of items followed by thenCancel() should
set the number of buffered to an arbitrary number greater than N.
This commit updates HttpWebHandlerAdapter and
ResponseStatusExceptionHandler in order to specify the method/uri in the
logged message.
It also logs a WARN message for bad request (400) HTTP responses in
order to get some logs when an exception is thrown due to client error
(unable to deserialize request body for example).
Issue: SPR-16447
Previously MockHttpServletRequestBuilder calculated the pathInfo from the
provided URL without decoding the value. This meant that the pathInfo
incorrectly included URL encoded values.
Now MockHttpServletRequestBuilder properly decodes the pathInfo.
Fixes: SPR-16453
MockHttpServletResponse no longer calls flushBuffer on calls to
getContentAsByteArray and getContentAsString. The flushing doesn't
actually do anything useful but does commit the response leading to
unexpected side effects.
Issue: SPR-16430
This commit adds these 2 Vary headers in addition to the existing
Origin one to avoid caching of Access-Control-Request-Method and
Access-Control-Request-Headers headers which can be an issue
when allowed methods or headers are unbounded and only the
requested method or headers are returned in the response.
Issue: SPR-16413
From:
Thymeleaf
Groovy Markup
FreeMarker
JSP & JSTL
Script Views
XML
Tiles
XSLT
PDF, Excel
RSS, Atom
Jackson
To:
Thymeleaf
FreeMarker
Groovy Markup
Script views
JSP & JSTL
Tiles
RSS, Atom
PDF, Excel
Jackson
XML
XSLT
Also move View Technologies after MVC Config to align order with
WebFlux config.
Issue: SPR-16393
The commit brings following changes:
- Move getDecodableMimeTypes() to AbstractJackson2Decoder
- Move getEncodableMimeTypes() to AbstractJackson2Encoder
- Add support for application/stream+x-jackson-smile
- Avoid streaming line separator when Smile encoder is used
- Use double null token in Jackson2Tokenizer to identify documents
Issue: SPR-16151
The resolved URI instance is also being cached now. This should not make a difference in a real Servlet environment but does affect tests which assumed they could modify an HttpServletRequest path behind a pre-created ServletServerHttpRequest instance. Our WebSocket test base class has been revised accordingly, re-creating the ServletServerHttpRequest in such a case.
Issue: SPR-16414
This commit makes sure there is no custom Content-Disposition header
before setting one automatically.
This commit also adds a headers(Consumer<HttpHeaders>) method, so that
one can user the nicer methods of HttpHeaders, as opposed to basic
strings.
Issue: SPR-16376
Since Java7 HttpURLConnection offers setFixedLengthStreamingMode method with long parameter which should be prefered over version with int argument, therefore casting ContentLength to int is no longer needed. Moreover it makes impossible to stream payload larger than Integer.MAX_VALUE
Now that SPR-16307 makes it possible to write a part with a Publisher
we need to ensure we get the filename correctly when writing with
Publisher<Resource>.
Issue: SPR-16376
After this commit DefaultUserDestinationResolves no longer looks at
whether AntPathMatcher is configured with "." as separator and rather
expects to be explicitly told whether to keep the leading slash in
translated destinations which actually depends on what the message
broker supports (e.g. RabbitMQ "/", Artemis ".") or how it is
configured (simple broker could be either way).
There is also a minor improvement in SimpMessagingTemplate to ensure
user destinations are correctly formed based on what the
DefaultUserDestinationResolver expects. When using "." as separtor it
allows sending messages to "queue.q1" rather than "/queue.q1".
Issue: SPR-16275
The previous fix #09f1f7 did not actually address the issue but only
moved it further down, so instead of the subscribe(), it was consuming
it inside the MultipartHttpMessageWriter#write method which returned
this.body.then(), and then again for the actual request body writing.
In this commit MultipartHttpMessageWriter#write returns Mono.empty()
since we don't actually want to write the part content from there, but
only want to access it as soon as it is availabele, for writing to
the request body.
Issue: SPR-16402
This commit checks the Etag/LastModified headers on the incoming
request, and sets a 304 Not Modified status with no body when they
match, by delegating to ServerWebExchange.checkNotModified.
Issue: SPR-16348
This commit separates the creation of a response so that it is executed
after the synchronized block inside which requests need to be matched
and validated (for order and count).
This allows a ResponseCreator to be slow or block if it has to.
Issue: SPR-16319
We cover this more succinctly from other places, e.g. in Model Methods
by referring to the Javadoc of Contentions, or pointing to the
RequestToViewNameTranslator.
As of EclipseLink 2.4.0 - Juno this is not sufficient to log
SQL parameter binding. Additionally,
eclipselink.logging.parameters must be enabled.
Issue: SPR-16383
After this commit, AbstractSockJsService uses the configured allowed
origins when generating the CorsConfiguration instead of "*".
As a consequence, forbidden origin requests still result in a 403
response but now with no CORS headers in order to improve consistency
between the status code and the headers.
Issue: SPR-16304
Use DataBufferUtils.compose instead of writeAggregator to combine
multiple data buffers into one, as the write aggregator would not work
when the initial data buffer did not have enough capacity to contain
all subsequent buffers.
Removed writeAggregator, as it is no longer needed.
Issue: SPR-16365
Added a utility method that composes data buffers into a single buffer.
Depending on the `DataBuffer` implementation, the returned buffer may be
a single buffer containing all data of the provided buffers, or it may
be a true composite that contains references to the buffers.
Issue: SPR-16365
The match/matches methods of UriTemplate use a regex with (.*) in place
of URI variables, which work fine except in the end where such a
pattern can match greedily more than one segment.
This commit updates the regex to use ([^/]*) instead since URI
variables are only meant to be used within a single path segment.
Issue: SPR-16169
Clarify what PathPatternParser is used for which is CORS checks in the
very least. Some sub-classes will also use it for request mapping but
not all (e.g. RouterFunctionMapping). Hence the need to be more
explicit.
@EnableWebFlux bootstraps both annotated controllers and functional
endpoints, so we need to be more explicit about which parts of the
configuration apply to which.
Issue: SPR-16360
This commit polishes SPR-16022 fix in order to handle correctly
the case when primary and default constructors are the same when
a secondary constructor is defined.
Issue: SPR-16289
As a consequence of dropping CompositeByteBuf (see prior commit),
DataBuffers fluxes that are aggregated with Flux.reduce(BiFunction) are
now required to be released, as the composite no longer holds a
reference to subsequent data buffers.
For this purpose, DataBufferUtils now has a writeAggregator that can be
used with Flux.reduce, and that released the subsequent buffers
properly.
Issue: SPR-16351
Prior to this commit, NettyDataBuffer had a optimization in
write(ByteBuf...), where it used a CompositeByteBuf to hold the original
and the parameter buffer.
Unfortunately, this procedure has nasty consequences when splicing
buffers (see https://stackoverflow.com/a/48111196/839733).
As of this commit, NettyDataBuffer stopped using CompositeByteBuf, and
simply does ByteBuf.write().
Issue: SPR-16351
Optimize same origin check when the request is an instance of
ServletServerHttpRequest and when there is no forwarded headers.
This commit also optimizes the getPort methods and ForwardedHeaderFilter
forwarded headers checks.
Issue: SPR-16262
This commit refines forwarded protocol support in order to support
proxies that only set "X-Forwarded-Proto" header and not
"X-Forwarded-Port" by performing a reset of the port in such case.
"Forwarded" header support has been updated accordingly since it
also supports similar use case, as described in SPR-15504.
Issue: SPR-16262
Since type erasure can be fixed only when using
ParameterizedTypeReference based Java methods, RestOperations and
WebFlux API documentation should be updated to specify which extensions
are subject to type erasure, and which are not.
Issue: SPR-16273
This allows us to confirm 0.7.3 fixes and run tests against the latest
ahead of an upgrade to Reactor Netty 0.8 snapshots.
The fix for #231 and #240 are confirmed but unfortunately test case for
This commit moves the ResolvableType field from HttpEntity to
PublisherEntity, a new entity type defined in MultipartBodyBuilder.
With this change, the scope of the ResolvableType is limited to
multipart-related code, instead of becoming part of the complete
HttpEntity hierarchy.
Issue: SPR-16307
This commit adds new header assertions for `WebTestClient`.
`doesNotExist` tests that a given header is not present:
.expectHeader().doesNotExist("Cache-Control");
`contentTypeCompatibleWith` tests for MediaType compatibility:
.expectHeader().contentTypeCompatibleWith("text/*");
Issue: SPR-16285
This commit adds a ResolvableType field to HttpEntity, in order to
support Publishers as multipart data. Without the type, the
MultipartHttpMessageWriter does not know which delegate writer to use to
write the part.
Issue: SPR-16307
This commit allows CorsConfiguration#combine()
to differentiate permit default values set by
CorsConfiguration#applyPermitDefaultValues()
from values configured explicitly by the user.
Those permit default values will be overridden
by any user-provided ones while user-provided values
will be combined in an additive way, including
when "*" is specified.
Documentation has been improved accordingly.
Issue: SPR-15772
With this commit, the default content-type defined by the
view (usually "text/html;charset=UTF-8" defined in AbstractView)
is used if any, when none is defined in the response headers.
Issue: SPR-16247
This commit removes the mention that Spring Boot 2.0 includes
Jackson Kotlin module since it is not the case as of M7, and
add a note about using bean validation annotations with Kotlin.
If the response is set and we can't change the status through
ServerHttpResponse any more, allow the error signal to propagate and
let the individual server adapters handle it. Ultimately that should
result in closing the connection.
On Servlet containers, we check one last time if the response is
committed (we may not have filled the buffer). If not then save
the exception as a request attribute, dispatch, and re-throw it on the
container thread.
On Undertow access the connection and close it.
On Netty just let the error through to Reactor Netty.
Issue: SPR-16051
Provide a fully mutable HttpHeaders to ClientHttpRequestInterceptors
of a RestTemplate when headers are set using HttpEntity. This avoids
UnsupportedOperationException if both HttpEntity and
ClientHttpRequestInterceptor add values for the same HTTP header.
Issue: SPR-15066
As of Gradle Kotlin plugin 1.1.60,
project.sourceSets.main.kotlin.srcDirs contains
Java source directories in addition to Kotlin
ones. This commit filter out Java sources to
retain only Kotlin ones.
Issue: SPR-16268
This commit fixes a bug where an IllegalStateException was
thrown if the minPort and maxPort values supplied to
SocketUtils.findAvailableTcpPort(int, int) were identical.
From #9a894a we began using the content-type from the ResponseEntity
but cross-checking it still against the requested content type.
Arguably there isn't any purpose in cross-checking. The only possible
outcomes are: a) it's compatible or b) it's not, which would result in
406 (NOT_ACCEPTABLE). As we've been given explicitly the media type to
use, it makes little sense to send 406, ignoring the wish to use that
content type.
Issue: SPR-16251
The request URI returned from HttpServerRequest.uri() typically
contains contains an absolute path but could also contain an
absolute URI. This commit adds handling for the latter, effectively
taking only the absolute path portion.
Issue: SPR-16243
apiVersion and languageVersion options are set to 1.1
on production code in order to avoid incompatibilities
with Kotlin 1.1 based projects or libraries.
Issue: SPR-16239
ResponseStatusExceptionHandler lets the error through if it can't
change the status while HttpWebHandlerAdapter logs a more helpful
message (including status code) but without a full stack trace.
Issue: SPR-16231
- Add "Processing" section (also replaces Advanced Customizations)
- Add information on out-of-the-box behavior
- Add more deails on @CrossOririn default configuratio
- Add cross-references between Spring MVC and WebFlux
- Polish
1. setComplete checks the isCommitted flag to avoid an unnecessary
debug message. This method is meant to be safe to call many times.
2. setStatusCode lowers log message to TRACE, since the return value
communicates the outcome it's arguably much less critical.
3. Add comment and test case for ResponseStatusExceptionHandler.
A ResponseStatusException is clearly meant to be handled by this
handler so don't let it pass through even if the respones is
committed.
Issue: SPR-16231
Before this commit, the return value from write was interpreted as the
data being fully written and ready to be released via releaseData().
This is not true for WebSocketSession implementations where a true
return value simply means the message was sent with the full payload
but releas is not appropriate until a send confirmation.
Technically not an issue since WebSocketSession's extending this do
not use pooled buffers. Nevertheless this commit refines the semantics
of write, removes the releaseData() method, and makes sub-classes
responsible for releasing the buffer when fully written (and they
know best when that is). As a bonus currentData is now private.
Issue: SPR-16207
After this commit, Tomcat and Undertow WebSocketSession imlpementations
start out in suspended mode and wait for demand.
The JettyWebSocketSession is capable of suspending but it doesn't seem
to work if invoked before any messages are received. That may become an
issue if there is a case where no demand appears long enough for more
messages to accumulate than we can hold.
UnderowServerHttpRequest would ideally also start in suspended mode but
that also doesn't work. It is not an issue in this case since we can
ignore the read notifications.
Servlet API requires a proactive check before it calls you back so
there is no need to suspend.
Issue: SPR-16207
This commit turns suspendReading() into a readingPaused() notification
that is invoked after a succession of reads stops because there is no
more demand. Sub-classes can use this notification to suspend, if that
applies to them.
Most importantly the notification is guaranteed not to overlap with
checkOnDataAvailable() which means that suspend does not need to be
atomic and guarded against resume. The two can and do compete all the
time when reading ends with no demand, and a request for demand arrives
concurrently.
Issue: SPR-16207
Access-Control-Allow-Credentials CORS header, used to
allow cookies with CORS requests, is not set to true
anymore by default when enabling CORS with
@CrossOrigin or global CORS configuration in order to
provide a more secured default CORS configuration.
The related allowCredentials property now requires to
be set to true explicitly in order to support cookies
with CORS requests.
Issue: SPR-16130
Transition from DEMAND->NO_DEMAND:
Two concurrent threads enter DEMAND.request and DEMAND.onDataAvailable.
And DEMAND.onDataAvailable finishes before DEMAND.request to be able to
update the demand field then a request for reading will be lost.
Transition from READING->NO_DEMAND:
readAndPublish() returns false because there is no demand but before
switching the states READING.request is invoked again a request for
reading will be lost.
Changing READING->DEMAND/NO_DEMAND is made conditional so that the
operations will be executed only if changing states succeeds.
When in READING state detect completion before each next item in order
to exit sooner, if completed.
Issue: SPR-16207
- Ensure completion signal (normal/exception) will be delivered to
the subscriber when transition from UNSUBSCRIBED->COMPLETED
- According to the specification "Publisher.subscribe MUST call onSubscribe
on the provided Subscriber prior to any other signals to that Subscriber" so
ensure onComplete/onError signals will be called AFTER onSubscribe signal.
Issue: SPR-16207
This commit changes the implementation of the PathPattern
extractPathWithinPattern method that used an old AntPathMatcher
derivative to a new version that integrates more closely with
PathContainer.
It also introduces consistency in a couple of areas. The javadoc
is updated to specify this but basically:
- the response from the extra method will have all leading
and trailing separators removed.
- the response will have multiple adjacent separators within the
reponse reduced to just one. (For example response would be
aaa/bb/cc and not aaa///bbb//cc)
If your response would start or finish with multiple separators, they
are all removed.
Issue: SPR-16120
- When there is no demand for reading, the implementation
should suspend reading otherwise useless events will be
send by Undertow to the registered read listener.
- There is not need to wait for an event for reading/writing after calling
resumeReads/resumeWrites
This commit adds
AbstractMessageReaderArgumentResolver#readBody and
AbstractMessageWriterResultHandler#writeBody variants
which allow to pass the actual MethodParameter in order
to perform proper annotation-based hint resolution with
nested generics, for example with HttpEntity.
Issue: SPR-16098
Autowiring implicitely Kotlin primary constructors
when there are secondary constructors has side effects
on ConstructorResolver. It seems reasonable to
require explicit @Autowired annotation in such case.
With this commit, implicit autowiring of Kotlin
primary constructors is only performed when there
is a primary constructor defined alone or with
a default constructor (define explicitly or
generated via the kotlin-noarg compiler plugin
or via optional constructor parameters with default
values).
Issue: SPR-16022
The EXTENSION_RECEIVER parameter of Kotlin's extension
methods appear as normal method parameters to Java and
thus require a name. The synthetic name "$receiver" is
used here, as it is not a valid Kotlin identifier,
but valid in Java.
Issue: SPR-16119
This commit uses the existing CompositeByteBuf if present, as opposed
to creating a new composite for every call to
NettyDataBuffer.write(ByteBuf...)
Issue: SPR-16180
Practically no changes to RxNetty for a year and efforts underway to
rebuild 0.6.x based on a current Reactor Netty base.
Aside from the extra time to run integration tests having two
Netty-based servers can also cause false alarms such as ByteBuf leaks
related to RxNetty.
Also remove ErrorDeferredResultProcessingInterceptor which was meant
to be package private to begin with as its peer
ErrorCallableProcessingInterceptor (also removed).
Create the buffer with at least the original sql length to avoid
multiple re-allocations
Add a fast path if the original sql doesn't contain any parameters
Includes fixes for invalid exception declarations in Mockito-based unit tests. Also includes FreeMarker 2.3.27, Commons Pool 2.4.3, JSON-P 1.1.2.
Issue: SPR-16157
This commit introduces a new AbstractReactiveWebInitializer in
spring-web that relies on WebHttpHandlerBuilder to detect request
processing infrastructure beans from an ApplicationContext.
This eliminates the need to create a DispatcherHandler, since it is
expected to be a Spring bean, and as a result the initializers in
spring-webflux have been deprecated.
Issue: SPR-16144
The RFCs around basic authentication don't explicitly disallow empty
usernames. On the other hand usernames containing colons are, as colons
are used to separate the username from the password.
SimpMessageTypeMessageCondition was lenient in matching the message
type, essentially matching on any non-null message type with an exact
match given a preference only in comparing mulitple matches.
This commit modifies matching logic to look for an exact match.
Issue: SPR-16109
FromHttpMessageWriter and MultipartHttpMessageWriter both support
MultiValueMap except the former supports String values only. This
presents an issue since either full generic type information must be
provided, which is cumbersome on the client side, or if left out there
is no good way to order the writers to make a proper decision.
This commit:
- refines the canWrite behavior of to not a
accept MultiValueMap without proper generic information unless the
MediaType is explicitly set providing a strong hint.
- modifies MultipartHttpMessageWriter to be configured with a
FormHttpMessageWriter so it can write both plan and multipart data with
the ability to properly differentiate based on actual map values.
Issue: SPR-16131
This avoids "IllegalStateException: Expectations already declared" when
a MockRestServiceServer is used after one request throws an exception.
Issues: SPR-16132
This commit changes the way Undertow's PooledByteBuffers are dealt with.
Previously, these buffers where closed as soon as all data was read. As
of this commit, the UndertowServerHttpRequest returns PooledDataBuffers
from getBody(), so that the buffers are released when release() is
called.
The "Build from Source" wiki page now consolidates build-related information
and is independent from "Release" information. The former is broadly of interest
to any contributor. The later is of interest to committers.
This commit decouples ExchangeResult from knowledge about
WiretapClientHttpRequest/Response both of which are now private to
WiretapConnector.
ExchangeResult takes ClientHttpRequest/Response instead along with
promises for the serialized request and response content in the form
of MonoProcessor<byte[]>.
This sets up the possibility for an ExchangeResult to be created
outside and independent of WebTestClient, should we decide to make its
constructor public.
Issue: SPR-16101
The main way CONTRIBUTING will be viewed is on Github and the output
is just not good enough to justify using asciidoctor vs md/txt as
the recommended on the Github help page for contributing guidelines.
For example it was attractive to use a TOC and that works on Github
but doesn't look good. In the end it's a very short TOC and
maintaining manually is easy enough and it's easier to control the
look.
The guidelines were originally created several years ago. This commit
does not fundamentally change anything but rather make the guidance
more compact.
The commit consolidates into into CONTRIBUTING.adoc information from
CONTRIBUTING-DOCUMENTATION.adoc and also the wiki page "The Lifecycle
of an Issue".
Directly inlined hasLength implementations for proper nullability detection in IntelliJ, assuming a hasText checked value is never null afterwards. Since the JVM is going to do this at runtime anyway, this is effectively equivalent but more indicative for source code introspection algorithms.
Issue: SPR-15540
A new HTTP/2 support section has been added in the Spring MVC
documentation. Also, a dedicated wiki page is created for specific
container support information.
Issue: SPR-15821
This commit exposes the ClientRequest's URL and HttpMethod fields via a
setter, so that they can be changed more easily in a request that was
created via ClientRequest.from(ClientRequest).
Issue: SPR-16093
This commit introduces various improvements in DataBuffer:
- DataBuffer now exposes its read and write position, as well as its
capacity and writable byte count.
- Added DataBuffer.asByteBuffer(int, int)
- DataBufferUtils.read now reads directly into a DataBuffer, rather than
copying a ByteBuffer into a DataBuffer
- TomcatHttpHandler now reads directly into a DataBuffer
Issues: SPR-16068 SPR-16070
MockMvc now properly detects the presence of an AsyncContext and
re-uses the response instance used to start it.
This commit also includes a minor fix in
ResponseBodyEmitterReturnValueHandler to ensure it does not disable
ETag related content buffering for reactive return values that do not
result in streaming (e.g. single value or collections).
Issue: SPR-16067
Includes redeclaration of CodecConfigurer.DefaultCodecs without concrete Jackson decoder/encoder references in order to avoid hard Jackson dependency.
Issue: SPR-16064
Before this commit, when adding filters to a builder obtained via
`WebClient.mutate()`, the filters were added both to the original client
as well as the mutated builder. This commit fixes that.
Issue: SPR-16059
Prior to this commit, the `ResourceWebHandler` would itself handle the
response with an HTTP 404 in many cases, including a missing static
resource.
This does not give a chance to `WebExceptionHandler` instances to handle
that error and, for example, display an error page.
See spring-projects/spring-boot#8625
Issue: SPR-16023
Prior to this commit, the Resource `HandlerMapping` configured by
`@EnableSpringMvc` would be set up with only one custom
`HandlerInterceptor` (the one exposing the `ResourceUrlProvider` for
resolving URLs of static resources).
This behavior is not consistent with the rest of the default
configuration which leverages the interceptors configured against the
interceptor registry (with possible user-provided ones).
This change allows to register interceptors against resource handling;
this can be useful for metrics purposes, as in
spring-projects/spring-boot#10335.
Issue: SPR-16034
The Javadoc on tag classes now has all the information including a
list of all tags at the package level, HTML tables listing tag
attributes in each tag class, and class level description that is
as good or in many cases better than what was in the reference.
Issue: SPR-16045
1. Move schemas to local appendix within each top-level section.
2. Link to Javadoc for JSP tags
3. Purge Class Spring usage information
Issue: SPR-16045
The WebTestClient now takes advantage of the support for decoding
response to Void.class in WebClient so that applications can use
expectBody(Void.class) to the same effect as using
response.bodyToMono(Void.class) as documneted on WebClient#exchange.
The top-level, no-arg returnResult method (added very recently) has been
retracted, since the use of returnResult at that level, i.e. without
consuming the response content, should be used mainly for streaming.
It shouldn't be used for "no content" scenarios.
Documentation and Javadoc have been udpated accordingly.
Use the ClientResponse methods bodyToMono and bodyToFlux rather than
passing in a BodyExtractor so that WebTestclient now also benefits from
the recently improved handling of Void.class.
Before this commit those were burried in the Appendix where few would
guess to look. Previously that information was at the top, so it makes
sense to point to the Github wiki from the index HTML page.
Also a general update of the index page. Since we have recently revised
the overview, we can simply point to it and keep it shorter.
The section listing now includes more details per section.
Before this commit WebClient documentation was also included from the
Integration section where the RestTemplate is documented. That is
convenient but results in duplicate content under different URLs.
This commit removes the include from the Integration section and leaves
Concrete server and client, reactive request and response
implementations should not have to be accessed outside their package.
They could be seen as private to their HttpHandler adapters and
ClientHttpConnector's respectively.
The one exception, WebSocket upgrades in spring-webflux, is an internal
framework use case, accommodated via downcast + accessors in the
abstract base classes.
Prior to this commit, the `WebClient` always throws a `ClassCastException`
when an error occurs in `bodyToMono(ParameterizedTypeReference)``, and
not the expected exception, as set up by `onStatus`
Issue: SPR-16025
Extract WebClient content into a separate file that is now included
both in the WebFlux and in the Integration sections.
This allows having RestTemplate and WebClient documented in one place
under Integration while also keeping the same included in the WebFlux
section too.
Prior to this commit, asking for a `Void` type using any of the
`ClientResponse#bodyTo*` methods would immediately return an empty
`Publisher` without consuming the response body.
Not doing so can lead to HTTP connection pool inconsistencies and/or
memory leaks, since:
* a connection that still has a response body being written to it cannot
be properly recycled in the connection pool
* incoming `DataBuffer` might not be released
This commit detects when `Void` types are asked as body types and in
those cases does the following:
1. Subscribe to the response body `Publisher` to allow the connection to
be returned to the connection pool
2. `cancel()` the body `Publisher` if the response body is not empty; in
that case, we choose to close the connection vs. consume the whole
response body
Those changes imply that `ClientHttpResponse` and other related
contracts don't need a `close()` method anymore.
Issue: SPR-16018
Includes unified detection of Kotlin's optional parameters in MethodParameter.isOptional(), reduces BeanUtils.findPrimaryConstructor to Kotlin semantics (for reuse in AutowiredAnnotationBeanPostProcessor), and finally introduces a common KotlinDetector delegate with an isKotlinType(Class) check.
Issue: SPR-15877
Issue: SPR-16020
Prior to this issue, SPR-15920 added this new `close()` method which was
supposed to be called to clean resources after response processing.
This commit changes the meaning of that method: calling `close()` will
close the underlying HTTP connection. This has to be called if the
response body is not consumed by the application, since at that point
the underlying connection might be in an inconsistent state if shared in
a connection pool.
Issue: SPR-15993
Now that WebSessionStore is in charge of expiration checks on retrieve
it makes sense to also update the lastAccessTime on retrieve at the
same time, saving the need to call it after a retrieve.
Issue: SPR-15963
It is no longer adequate to list supported arguments and return values
-- between Web MVC and WebFlux, directly on the annotation.
Instead we have tables in the respective chapters in the reference with
cross references to each other.
Issue: SPR-15149
This commit makes Reactor Netty `WebClient` instances
support zero-copy requests by implementing `ZeroCopyHttpOutputMessage`.
The implementation leverages the optimized `sendFile` mechanism if
available.
This commit moves WebFluxUriComponentsBuilder.fromServerRequest to the
ServerRequest interface itself.
Consequently, the WebFluxUriComponentsBuilder is removes itself, as it
contained no other methods.
Issue: SPR-15953
The typical way to load DispatcherHandler is to use
WebHttpHandlerBuilder#applicationContext which also detecs filters,
exception handlers, as well as other beans that are injected into every
ServerWebExchange -- custom session manager, localecontext resolver,
codecs for form data, multipart data, etc
WebHttpHandlerBuilder is the preferred and way so removing the ones on
DispatcherHandler. They could always be added back later.
This commit introduces a visitor for router functions
(RouterFunctions.Visitor), allowing to iterate over all the components
that make up a router function.
This commit also introduces a ToStringVisitor, which creates a nicely
formatted string for use with toString().
Issue: SPR-15711, SPR-15711
Also, ChannelRegistration.setInterceptors is deprecated now: in favor of a fluently named interceptors(...) method which is documented to add the given interceptors to the channel's current list.
Issue: SPR-15962
Issue: SPR-15976
This commit makes sure that any custom MessageConverter set in a
JmsTemplate used by a JmsMessagingTemplate is reused as the payload
converter of the message.
Issue: SPR-15965
This commit introduces the WebFluxUriComponentsBuilder, with a single
method that creates a UriComponentsBuilder for a ServerRequest. More
methods to be added by @rstoyanchev.
Issue: SPR-15953
This commit introduces a methodName() method to the ServerRequest,
returning the String name of the method. This method is useful for
non-standard HTTP methods.
This commit introduces the following changes.
1) It adds a new Spring @NonNull annotation which allows to apply
@NonNullApi semantic on a specific element, like @Nullable does.
Combined with @Nullable, it allows partial null-safety support when
package granularity is too broad.
2) @Nullable and @NonNull can apply to ElementType.TYPE_USE in order
to be used on generic type arguments (SPR-15942).
3) Annotations does not apply to ElementType.TYPE_PARAMETER anymore
since it is not supported yet (applicability for such use case is
controversial and need to be discussed).
4) @NonNullApi does not apply to ElementType.FIELD anymore since in a
lot of use cases (private, protected) it is not part for the public API
+ its usage should remain opt-in. A dedicated @NonNullFields annotation
has been added in order to set fields default to non-nullable.
5) Updated Javadoc and reference documentation.
Issue: SPR-15756
When writing Publisher<Publisher<T>>, a flush operation is performed onComplete
for every Publisher. If the flush operation is not able to be performed immediately
it will be retried before starting to process data provided by the next Publisher.
For the last Publisher the implementation needs to ensure that the flush will
be performed only then whole operation will complete.
Issue: SPR-15949
This commit introduces a ForwardedHeaderFilter for WebFlux, similar to
the existing Servlet version. As part of this the
DefaultServerHttpRequestBuilder had to be changed to no longer use
delegation, but instead use a deep copy at the point of mutate().
Otherwise, headers could not be removed.
Issue: SPR-15954
This commit fixes a typo in the `DefaultWebClient` implementation.
Instead of forwarding resolved `WebClientException` instances as error
signals, the `bodyToMono(ParameterizedTypeReference)` variant would just
forward those exceptions as `onNext` signals.
Issue: SPR-15946
Prior to that commit, the `ResponseSpec` `WebClient` would process error
responses (4xx, 5xx HTTP status) and transform those into error signals
with a `WebClientResponseException`. But this would only work if the
HTTP response would have a non-empty response body.
An empty error response would not send an error signal and only
translate in an `onComplete` signal.
This commit fixes this behavior and makes sure that this error signal is
sent in all cases.
Issue: SPR-15946
Now that https://github.com/reactor/reactor-netty/issues/138 is solved,
this commit removes the temporary workaround introduced in SPR-15784
but leaves the general mechanism for detecting empty responses.
The high level matchStarting API was removed a few commits ago.
This change tidies up by removing the supporting infrastructure
for that from the PathElements.
Prior to this commit, various dependencies in the spring-test module
pulled in commons-logging as a transitive dependency. Consequently,
the presence of commons-logging in the generated Eclipse classpath
overrode the intended use of the spring-jcl module causing JUL to be
used instead of log4j for tests executed within Eclipse, thereby
ignoring the configuration in src/test/resources/log4j2-test.xml.
This commit addresses this issue by excluding commons-logging in
spring-test.gradle for all Selenium dependencies.
Issue: SPR-15930
InMemoryWebSessionStore is very closely associated to DefaultWebSession
passing it to it several fields and functions. Now that the store also
creates the session, it makes sense to bring the latter in as an inner,
nested class.
Issue: SPR-15875, 15876
DefaultWebSessionManager no longer requires the WebSessionStore
to use DefaultWebSession.
Removed explicit start() in save(). This seemed unnecessary since at
that point isStarted is guaranteed to return true. The status can
be updated through the copy constructor.
DefaultWebSessionTests added.
Issue: SPR-15875
- Add WebSessionStore.createWebSession.
- Remove remove WebSessionStore.changeSessionId
- Add WebSessionStore updateLastAccessTime which allows updating the
WebSession lastAccessTime without exposing a method on WebSession in
an implementation independent way.
- Remove WebSessionStore.storeSession. This method is not necessary
since the WebSession that is returned allows saving the WebSession.
Additionally, it is error prone since the wrong type might be passed
into it.
Issue: SPR-15875, 15876
Add missing DefaultWebSessionManagerTests .block(). Previously
session.save() was invoked, but we did not ensure it was completed.
This commit makes it block on session.save()
Fix existingSessionIsExpired. This test is actually broken and is
testing a new session is created because the session id returned
by the idResolver does not match the existing WebSession.
This commit ensures that the id of the WebSession found by idResolver
matches the existing WebSession.
DefaultWebSessionManagerTests use Mockito. To ensure we test with
independence from InMemoryWebSessionStore we use Mockito for the
DefaultWebessionManager collaborators.
Add test for response.setComplete(). We want to ensure that when the
response is completed, it saves the WebSession and writes it to the
response using idResolver
Use constant for default header name and make getHeaderName private.
Also switch HeaderWebSessionIdResolverTests to unit tests rather than
testing with DefaultWebSessionManager.
Issue: SPR-15917
Before this commit, there was no way to signal the HTTP client that we
were done consuming the response. Without that, the underlying client
library cannot know when it is safe to release the associated resources
(e.g. the HTTP connection).
This commit adds new `close()` methods on both `ClientHttpResponse`
and `ClientResponse`. This methods is non-blocking and its behavior
depends on the library, its configuration, HTTP version, etc.
At the `WebClient` level, `close()` is called automatically if we
consume the response body through the `ResponseSpec` or the
`ClientResponse` itself.
Note that it is *required* to call `close()` manually otherwise; not
doing so might create resource leaks or connection issues.
Issue: SPR-15920
This commit introduces a test that demonstrates that custom JUnit 4
rules can be @Autowired into a test instance but that they will not be
applied by JUnit since JUnit only ever sees such fields as null and
therefore ignores them.
Issue: SPR-15927
This commit moves `encodeUrl` and `registerUrlEncoder` from
ServerHttpResponse to ServerWebExchange.
It also renames `encodeUrl` to `transformUrl` and `registerUrlEncoder`
to `addUrlTransformer` to make it clearer that these methods do not
perform actual URL encodings (i.e. they do not replaceinvalid
characters).
The `add` prefix (instead of `register`) makes it clearer that each
function is added in addition to the previous one.
Issue: SPR-15924
Introduces HeaderSessionIdResolver, which reads session ids from a session header and generates a session response header when new session are created.
Related issue: SPR-15917
`ReactorClientHttpConnector` provides an adapter layer to `WebClient`
for using Reactor-Netty's `HttpClient`.
This commit enables HTTP compression support by default for this client
Connector.
Another constructor is still available for providing a custom
`HttpOptions` configuration.
Issue: SPR-15908
Prior to this commit, HTTP Range requests were only supported by the
ResourceHttpRequestHandler when serving static resources.
This commit improves the `HttpEntityMethodProcessor` and
the `RequestResponseBodyMethodProcessor`. They now extract
`ResourceRegion`s from the `Resource` instance returned by the
Controller and let the Resource-related message converters
handle the writing of the resource (including partial writes).
Controller methods can now handle Range requests for
return types that extend Resource or HttpEntity:
@RequestMapping("/example/video.mp4")
public Resource handler() { }
@RequestMapping("/example/video.mp4")
public HttpEntity<Resource> handler() { }
Issue: SPR-15789, SPR-13834
This change allows much more usable TOC for the reactive
stack and will make WebFlux documentation easier to
contribute thanks to a clearer split between both stacks.
Issue: SPR-15149
The upgrade to Gradle 4.0 broke the custom Eclipse support in the
Spring Framework build.
This commit includes the following changes which re-enable support for
Eclipse in the build.
- Switched to ProjectDependency(String) constructor
- Updated regular expression that matches against project output
dependencies to include more than one subdirectory between "build"
and "main"|"test".
Issue: SPR-15862
This commit adds support for autowired constructor parameters
on Kotlin classes with optional parameters. If some constructor
parameters are not available, optional parameter default values
will be used instead. Both explicit @Autowired annotated constructor
and implicit single constructor automatically autowired are supported.
Issue: SPR-15847
This commit reinstates the Spring Framework BOM, which was previously
empty because of a previous change in 41cbc4670f.
This change also removes the JSR305 dependency from the BOM, which does
not belong here since it is not an artifact produced by Spring.
Issue: SPR-15885
This commit ensures that only the HTML version of the reference
documentation is rendered for SNAPSHOT builds. This speeds up
significatly the build.
Issue: SPR-15885
As of Gradle 4.0, project SourceSets can have multiple output
directories (one per programming language).
This commit fixes warnings that are logged when a single output dir
is considered by tasks.
Issue: SPR-15885
This commit applies the Dependency Management Plugin to modules that
require it; right now Spring Framework is importing BOMs for Netty and
Reactor dependencies only.
Instead of applying those BOMs to all modules, they're applied only
where they're needed.
Issue: SPR-15885
The main `build.gradle` file contains now only the common build
infrastructure; all module-specific build configurations have
been moved to their own build file.
Issue: SPR-15885
This commit merges back the "spring-beans-groovy" module into the main
"spring-beans" one. The build is configured so:
* Java and Groovy sources are jointly compiled
* Kotlin sources are compiled after
With this change, the `MergePlugin` is not used anymore in the project
build and therefore is removed.
The `DetectSplitPackagesPlugin` wasn't applied so it's been removed as
well.
Issue: SPR-15885
With this change, each subproject can configure its
build in a dedicated file like:
```
spring-core/spring-core.gradle
spring-web/spring-web.gradle
```
Issue: SPR-15885
This commit configures Gradle build scans for the Spring Framework
build. Scans aren't performed for every build but can be enabled
with the following:
```
./gradlew build --scan
```
Issue: SPR-15885
Includes general streamlining of dependency declarations with reduced version variables, direct use of EclipseLink 2.7 and its implicit JPA 2.2 dependency in spring-orm, mixed use of Hibernate 5.2.10 and 5.1.10 for integration tests, as well as an upgrade to Jetty 9.4.7 RC0 and a downgrade to Groovy 2.4.12 (since Groovy 2.5 won't be final in time for Spring Framework 5.0).
Issue: SPR-15879
Issue: SPR-15880
Bean-derived null values may still get passed into bean properties and injection points but only if those are declared as non-required. Note that getBean will never return null; a manual bean.equals(null) / "null".equals(bean.toString()) check identifies expected null values now. This will only ever happen with custom FactoryBeans or factory methods returning null - and since all common cases are handled by autowiring or bean property values in bean definitions, there should be no need to ever manually check for such a null value received from getBean.
Issue: SPR-15829
Refer to both Servlet and reactive stacks in web.adoc
Move web-integration.adoc to the very end
Link in web-flux-functional.adoc
Insert "Spring Web MVC" or "Servlet" prefix in chapter titles
Issue: SPR-15149
This commit restores and existing redirectedUrl and forwardedUrl
methods (simple String comparison) and creates separate
redirectedUrlTemplate and forwardedUrlTemplate methods that expand
and also encode before comparing.
Issue: SPR-15834
This commit revises the implementation of the SpringExtension to use
the getRequired*() methods in the ExtensionContext which are now built
into JUnit Jupiter thanks to inspiration from the initial "convenience"
methods implemented here.
The PathPattern compareTo method is now consistent with equals when
two patterns are of the same specificity but otherwise different.
Separately PathPattern now exposes a Comparator by specificity that
offers the current functionality of compareTo. This can be used for
actual sorting where we only care about specificity.
Consistent behavior with matches(PathContainer), the two had slightly
different logic for handling of empty paths.
Make matchAndExtract independantly usable without the need to call
matches(PathContainer) first. Essentially no longer raising ISE if the
pattern doesn't match but simply returning null.
Rename getPathRemaining to matchStartOfPath since the method does
match and to be more clear about what the method and the return value
intuitively follows.
Remove matchStart which matches the start of the pattern (rather than
the start of the path). It is a use case that does not come up in
request mapping.
This commit changes the WebClient so that it now throws a
`WebClientResponseException` for `ResponseSpec.bodyTo`. This newly
introduces exception contains the status code, headers, and body of the
response message.
As a consequence of the above, we had to change `onStatus` so that the
`exceptionFunction` now returns a `Mono<Throwable>` rather than a
`Throwable`, which it was before. The Mono allows for asynchronous
operations, such as reading the contents of the body.
Issue: SPR-15824
Remove the separator constructor argument (but preserve internal
functionality) now that PathPatternParser is more explicitly purposed
for URL paths and in any case the use of an alternate separator would
also requires a similar input option on the PathContainer parsing side.
Re-arrange the checks so that if there is no form parameter, then
immediately and unconditionally delegate to super.getParameterValues().
Or reversely if there is no super.getParameterValues() then return the
form parameter.
So the only remaining case is when combining values present in both.
In that case we'll take both only if a queryString exists.
One extra fix is to not even wrap the request if we did not parse any
form parameters at all which can happen with HttpHiddenMethodFilter.
Issue: SPR-15828, 15835
Removed superfluous `fromServerSentEvent` variants from `BodyInserters`,
as their functionality can also be obtained by passing a stream of
strings or POJOs (to be encoded as JSON) to
`fromPublisher(Publisher, Class)}`, and specifying a `text/event-stream`
Content-Type.
Issue: SPR-15826
This commit also removes WebFlux non-extension functions in favor of
regular Kotlin extensions leveraging ParameterizedTypeReference parameter.
Issue: SPR-15818
This commit changes the usage of two separate attributes (username and
password) into one: a single `Credentials` object.
Additionally, the attributes key under which the credentials are stored
is changed to be specific to Basic Authentication, in order to allow for
other sorts of authentication later.
Issue: SPR-15764
This commit changes adds overloaded `ParameterizedTypeReference `
variants to body-related methods in `ServerRequest` and
`ServerResponse`.
It also adds a single PTR variant to ClientRequest, which was missing
before.
Issue: SPR-15817
This commit changes all consumers of CodecConfigurer to consume a `List`
of HttpMessageReaders or HttpMessageWriters instead of consuming the
Server- or ClientCodecConfigurer directly.
Issue: SPR-15816
By using function literals with receiver, we can avoid requiring
lambda parameters for a shorter and nicer syntax. Based on a
proposal from Joseph Taylor.
Issue: SPR-15815
_Have something you'd like to contribute to the framework? We welcome pull
requests but ask that you carefully read this document first to understand how
best to submit them; what kind of changes are likely to be accepted; and what
to expect from the Spring team when evaluating your submission._
# Contributing to the Spring Framework
_Please refer back to this document as a checklist before issuing any pull
request; this will save time for everyone!_
First off, thank you for taking the time to contribute! :+1: :tada:
## Code of Conduct
This project adheres to the Contributor Covenant [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.
### Table of Contents
## Take Your First Steps
* [Code of Conduct](#code-of-conduct)
* [How to Contribute](#how-to-contribute)
* [Discuss](#discuss)
* [Create a Ticket](#create-a-ticket)
* [Ticket Lifecycle](#ticket-lifecycle)
* [Submit a Pull Request](#submit-a-pull-request)
* [Build from Source](#build-from-source)
* [Source Code Style](#source-code-style)
* [Reference Docs](#reference-docs)
### Understand the basics
### Code of Conduct
Not sure what a pull request is, or how to submit one? Take a look at GitHub's
excellent [help documentation][] first.
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.
### Search Stack Overflow first; discuss if necessary
### How to Contribute
If you're unsure why something isn't working or wondering if there is a better
way of doing it please check on Stack Overflow first and if necessary start
a discussion. This is the official list of
[Spring project tags](https://spring.io/questions). In short the issue tracker
should be used to report issues and make feature requests.
#### Discuss
### Search JIRA; create an issue if necessary
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.
Is there already an issue that addresses your concern? Do a bit of searching
in our [JIRA issue tracker][] to see if you can find something similar. If you
do not find something similar, please create a new JIRA issue before submitting
a pull request unless the change is truly trivial -- for example: typo fixes,
removing compiler warnings, etc.
If you suspect an issue, perform a searchin the
[GitHub issue tracker](https://github.com/spring-projects/spring-framework/issues), 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.
### Sign the Contributor License Agreement (CLA)
#### Create a Ticket
If you have not previously done so, please sign the [Contributor License Agreement][].
If you forget to do so, you'll be reminded when you submit a pull request.
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.
## Create a Branch
Before you create a ticket, please take the time to [research first](#discuss).
### Branch from `master`
If creating a ticket after a discussion on StackOverflow, please provide a self-sufficient description in the ticket, independent of the details on StackOverflow. 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.
Master currently represents work toward Spring Framework 5.0. Please submit
all pull requests there, even bug fixes and minor improvements. Backports to
`4.3.x` will be considered on a case-by-case basis.
When ready create a ticket in the [GitHub issue tracker](https://github.com/spring-projects/spring-framework/issues).
#### Ticket Lifecycle
### Use short branch names
When an issue is first created, it is flagged `waiting-for-triage` waiting for a team
member to triage it. Within a day or two, the issue will then be reviewed and the team
may ask for further information if needed. Based on the findings, the issue is either
assigned a fix version or declined.
Branches used when submitting pull requests should preferably be named
according to JIRA issues, e.g. 'SPR-1234'. Otherwise, use succinct, lower-case,
dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. In
[fork-and-edit][] cases, the GitHub default 'patch-1' is fine as well. This is
important, because branch names show up in the merge commits that result from
accepting pull requests and should be as expressive and concise as possible.
When a fix is ready, the issue is closed and may still be re-opened. Once a fix is
released, the issue can't be reopened. If necessary, you will need to create a new,
related ticket with a fresh description.
## Use Spring Framework Code Style
#### Submit a Pull Request
The complete [Spring Framework Code Style][] reference is available on the wiki, but
here's a quick summary:
You can contribute a source code change by submitting a pull request.
### Mind the whitespace
1. If you have not previously done so, please sign the
[Contributor License Agreement](https://cla.pivotal.io/sign/spring). You will also be reminded
automatically when you submit a pull request.
Please carefully follow the whitespace and formatting conventions already
present in the framework.
1. Should you create a ticket first? The answer is no. Just create the pull request and use
the description to provide context and motivation, as you would for an issue. If you want
to start a discussion first or have already created an issue, once a pull request is created,
we will close the issue as superseded by the pull request, and the discussion of the issue
will continue under the pull request.
1.Tabs, not spaces
1. Unix (LF), not DOS (CRLF) line endings
1. Eliminate all trailing whitespace
1. Wrap Javadoc at 90 characters
1. Aim to wrap code at 90 characters, but favor readability over wrapping
1. Preserve existing formatting; i.e. do not reformat code for its own sake
1. Search the codebase using `git grep` and other tools to discover common
naming conventions, etc.
1. UTF-8 encoding for Java sources
1.Always check out the `master` branch and submit pull requests against it
(for target version see [settings.gradle](settings.gradle)).
Backports to prior versions will be considered on a case-by-case basis and reflected as
the fix version in the issue tracker.
1. Use short branch names, preferably based on the GitHub issue (e.g. `22276`), or
otherwise using succinct, lower-case, dash (-) delimited names, such as `fix-warnings`.
### Add Apache license header to all new classes
1. Choose the granularity of your commits consciously and squash commits that represent
multiple edits or corrections of the same logical change. See
[Rewriting History section of Pro Git](https://git-scm.com/book/en/Git-Tools-Rewriting-History)
for an overview of streamlining commit history.
```java
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
1. Format commit messages using 55 characters for the subject line, 72 characters per line
for the description, followed by the issue fixed, e.g. `Closes gh-22276`. See the
[Commit Guidelines section of Pro Git](https://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines)
for best practices around commit messages and use `git log` to see some examples.
package...;
```
1. List the GitHub issue number in the PR description.
### Update Apache license header in modified files as necessary
If accepted, your contribution may be heavily modified as needed prior to merging.
You will likely retain author attribution for your Git commits granted that the bulk of
your changes remain intact. You may also be asked to rework the submission.
Always check the date range in the license header. For example, if you've
modified a file in 2017 whose header still reads:
If asked to make corrections, simply push the changes against the same branch, and your
pull request will be updated. In other words, you do not need to create a new pull request
when asked to make changes.
```java
/*
*Copyright2002-2011theoriginalauthororauthors.
```
#### Participate in Reviews
Then be sure to update it to 2017 accordingly:
Helping to review pull requests is another great way to contribute. Your feedback
can help to shape the implementation of new features. When reviewing pull requests,
however, please refrain from approving or rejecting a PR unless you are a core
committer for the Spring Framework.
```java
/*
*Copyright2002-2017theoriginalauthororauthors.
```
### Build from Source
### Use @since tags for newly-added public API types and methods
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)
wiki page for instructions on how to check out, build, and import the Spring Framework
source code into your IDE.
For example:
### Source Code Style
```java
/**
* ...
*
* @author First Last
* @since 5.0
* @see ...
*/
```
The wiki pages
[Code Style](https://github.com/spring-projects/spring-framework/wiki/Code-Style) and
[IntelliJ IDEA Editor Settings](https://github.com/spring-projects/spring-framework/wiki/IntelliJ-IDEA-Editor-Settings)
defines the source file coding standards we use along with some IDEA editor settings we customize.
## Prepare Your Commit
### Reference Docs
### Submit JUnit test cases for all behavior changes
The reference documentation is in the [src/docs/asciidoc](src/docs/asciidoc) directory and, in
[Asciidoctor](https://asciidoctor.org/) format. For trivial changes, you may be able to browse,
edit source files, and submit directly from GitHub.
Search the codebase to find related tests and add additional `@Test` methods
as appropriate. It is also acceptable to submit test cases on a per JIRA issue
basis, for example:
When making changes locally, use `./gradlew asciidoctor` and then browse the result under
`build/asciidoc/html5/index.html`.
```java
packageorg.springframework.beans.factory.support;
/**
* Unit tests for SPR-8954, in which a custom {@link InstantiationAwareBeanPostProcessor}
* forces the predicted type of a FactoryBean, effectively preventing retrieval of the
* bean from calls to #getBeansOfType(FactoryBean.class). The implementation of
* {@link AbstractBeanFactory#isFactoryBean(String, RootBeanDefinition)} now ensures
* that not only the predicted bean type is considered, but also the original bean
* definition's beanClass.
*
* @author Chris Beams
*/
publicclassSpr8954Tests{
@Test
publicvoidcornerSpr8954(){
// ...
}
}
```
### Squash commits
Use `git rebase --interactive --autosquash`, `git add --patch`, and other tools
to "squash" multiple commits into a single atomic commit. In addition to the man
pages for git, there are many resources online to help you understand how these
tools work. The [Rewriting History section of Pro Git][] provides a good overview.
### Use real name in git commits
Please configure git to use your real first and last name for any commits you
intend to submit as pull requests. For example, this is not acceptable:
Author: Nickname <user@mail.com>
Rather, please include your first and last name, properly capitalized, as
submitted against the Spring Individual Contributor License Agreement (ICLA):
Author: First Last <user@mail.com>
This helps ensure traceability against the ICLA and also goes a long way to
ensuring useful output from tools like `git shortlog` and others.
You can configure this via the account admin area in GitHub (useful for
fork-and-edit cases); _globally_ on your machine with
git config --global user.name "First Last"
git config --global user.email user@mail.com
or _locally_ for the `spring-framework` repository only by omitting the
'--global' flag:
cd spring-framework
git config user.name "First Last"
git config user.email user@mail.com
### Format commit messages
Please read and follow the [Commit Guidelines section of Pro Git][].
Most importantly, please format your commit messages in the following way
(adapted from the commit template in the link above):
Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded by a
single space, with blank lines in between, but conventions vary here
Issue: SPR-1234, SPR-1235
1. Use imperative statements in the subject line, e.g. "Fix broken Javadoc link".
1. Begin the subject line with a capitalized verb, e.g. "Add, Prune, Fix,
Introduce, Avoid, etc."
1. Do not end the subject line with a period.
1. Restrict the subject line to 50 characters or less if possible.
1. Wrap lines in the body at 72 characters or less.
1. Mention associated JIRA issue(s) at the end of the commit comment, prefixed
with "Issue: " as above.
1. In the body of the commit message, explain how things worked before this
commit, what has changed, and how things work now.
For examples of this style, issue a `git log --author=cbeams` in the
`spring-framework` git repository. For convenience, here are several such commits:
The Spring Framework provides a comprehensive programming and configuration
model for modern Java-based enterprise applications -- on any kind of deployment
platform. A key element of Spring is infrastructural support at the application
level: Spring focuses on the "plumbing" of enterprise applications so that teams
can focus on application-level business logic, without unnecessary ties to
specific deployment environments.
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework [](https://build.spring.io/browse/SPR)
The framework also serves as the foundation for [Spring Integration][], [Spring Batch][]
and the rest of the Spring [family of projects][]. Browse the repositories under
the [Spring organization][] on GitHub for a full list.
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 is often referred to simply as "Spring".
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 adheres to the Contributor Covenant [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.
## Downloading Artifacts
See [downloading Spring artifacts][] for Maven repository information. Unable to
use Maven or other transitive dependency management tools?
See [building a distribution with dependencies][].
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 [Spring Framework Artifacts](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts) wiki page.
## Documentation
See the current [Javadoc][] and [reference docs][].
## Getting Support
Check out the [spring][spring tags] tags on [Stack Overflow][]. [Commercial support][]
is available too.
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.
## Issue Tracking
Report issues via the [Spring Framework JIRA][]. Understand our issue management
process by reading about [the lifecycle of an issue][]. Think you've found a
bug? Please consider submitting a reproduction project via the
[spring-framework-issues][] GitHub repository. The [readme][] there provides
simple step-by-step instructions.
## Build from Source
## Building fromSource
The Spring Framework uses a [Gradle][]-based build system. In the instructions
below, [`./gradlew`][] is invoked from the root of the source tree and serves as
a cross-platform, self-contained bootstrap mechanism for the build.
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.
### Prerequisites
## Stay in Touch
[Git][] and [JDK 8 update 20 or later][JDK8 build]
Be sure that your `JAVA_HOME` environment variable points to the `jdk1.8.0` folder
Run `./import-into-eclipse.sh` or read `import-into-idea.md` as appropriate.
> **Note:** Per the prerequisites above, ensure that you have JDK 8 configured properly in your IDE.
### Install all spring-\* jars into your local Maven cache
`./gradlew install`
### Compile and test; build all jars, distribution zips, and docs
`./gradlew build`
... and discover more commands with `./gradlew tasks`. See also the [Gradle
build and release FAQ][].
## Contributing
[Pull requests][] are welcome; see the [contributor guidelines][] for details.
## Staying in Touch
Follow [@SpringCentral][] as well as [@SpringFramework][] and its [team members][]
on Twitter. In-depth articles can be found at [The Spring Blog][], and releases
are announced via our [news feed][].
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 [Apache License][].
// 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)
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://www.eclipse.org/ajdt/downloads/) (_AJDT_) if you need to work with the `spring-aspects` project.
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.
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +20,7 @@ package org.aopalliance.aop;
* Superclass for all AOP infrastructure exceptions.
* Unchecked, as such exceptions are fatal and end user
* code shouldn't be forced to catch them.
*
*
* @author Rod Johnson
* @author Bob Lee
* @author Juergen Hoeller
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.