This commit correctly identifies MaxUploadSizeExceededException in
StandardMultipartHttpServletRequest by converting keywords in the
exception message to lowercase before checking for their presence, for
compatibility with Jetty 9.4.x.
Closes gh-28759
Reactor Netty M4 brings in a dependency on context-propagation, so we
need the milestone repository. The dependency will become optional for
M5, so we only need this temporarily.
See gh-28766
- update handler methods for lower level exceptions to create a mapping
to a ProblemDetail.
- add protected method for creating the ResponseEntity that a subclass
can override to re-create ProblemDetail without overriding the rest
of what handleExceptionInternal does.
- update Javadoc and polishing
See gh-28439
Since gh-28781 is still open for team discussion, this commit removes
the `String...` variant for AopProxyUtils.completeJdkProxyInterfaces.
Depending on the outcome of gh-28781, this method may be reintroduced
in 6.0 M6.
Closes gh-28745
Prior to this commit, when users wished to register proxy hints for a
Spring AOP JDK dynamic proxy, they were required to explicitly specify
SpringProxy, Advised, and DecoratingProxy along with user interfaces.
This commit simplifies hint registration for Spring AOP proxies by
introducing two completeJdkProxyInterfaces() methods in AopProxyUtils,
one that accepts strings and one that accepts classes that represent
the user-specified interfaces implemented the user component to be
proxied. The SpringProxy, Advised, and DecoratingProxy interfaces are
appended to the user-specified interfaces and returned as the complete
set of interfaces that the proxy will implement.
Closes gh-28745
Since users might not have a concrete need to work with TypeReference,
this commit introduces ProxyHints.registerJdkProxy(String...) to
simplify use of the API for registering a dynamic proxy based on fully
qualified class names of the required interfaces.
Closes gh-28781
The warning message logged for an annotation that still uses
convention-based overrides now includes a concrete suggestion for how
the problem may potentially be fixed.
WARN - Support for convention-based annotation attribute overrides is
deprecated and will be removed in Spring Framework 6.1. Please
annotate the 'locations' attribute in
@org.springframework.core.annotation.MergedAnnotationsTests$ConventionBasedComposedContextConfiguration
with an appropriate @AliasFor declaration -- for example,
@AliasFor(annotation = org.springframework.core.annotation.MergedAnnotationsTests$ContextConfiguration.class).
See gh-28760
This commit replaces convention-based annotation attribute overrides in
tests with explicit use of @AliasFor -- except for tests in spring-core,
since we still want to test our support for convention-based annotation
attribute overrides.
See gh-28760
This commit introduces a TransactionBeanRegistrationAotProcessor
in charge of creating the required proxy and reflection hints
when @Transactional is detected on beans.
It also refines DefaultAopProxyFactory to throw an exception
when a subclass-based proxy is created in native images
since that's unsupported for now (see gh-28115 related issue).
Closes gh-28717
This commit deprecates all methods in org.springframework.scheduling
that use
- Date, in favor of variants that take an Instant.
- long & TimeUnit, in favor of variants that take a Duration.
Closes: gh-28714
Implicit convention-based annotation attribute overrides have been
supported for a long time; however, Spring Framework 4.2 introduced
support for explicit annotation attribute overrides via @AliasFor.
Since explicit overrides are favorable to implicit overrides, and since
the support for convention-based overrides increases the complexity of
Spring's annotation search algorithms, this commit deprecates
convention-based overrides and logs a WARNING whey the are encountered.
For example, the following message is logged for a test that still
uses convention-based overrides. A log message is generated for each
such attribute in a given annotation but only once per application run.
WARN Support for convention-based annotation attribute overrides is
deprecated and will be removed in Spring Framework 6.1. Please
annotate the 'basePackages' attribute in
@org.springframework.context.annotation.ConfigurationClassPostProcessorTests$ComposedConfigurationWithAttributeOverrides
with an appropriate @AliasFor declaration.
Closes gh-28760
AnnotationTypeMapping.addConventionMappings() sometimes adds
convention-based mappings that it should not.
For example, in certain circumstances an explicit annotation attribute
override configured via @AliasFor can be incorrectly mapped as
convention-based.
Although this does not appear to cause negative side effects (other
than unnecessary processing), this is technically a bug, and this
commit address this issue.
Closes gh-28773
This commit annotates @Transactional with @Reflective
and registers proxy hints for SpringProxy.
Injection of proxied beans via their interfaces still fails
in native images with a
"No qualifying bean of type MyInterface" error.
See gh-28717
Prior to this commit, tests in these two classes intermittently failed
with errors similar to the following, due to concurrent modification
of shared files.
expected:
"<input type="text" id="name" name="name" value="Darren" >"
but was:
"<input type="text" id="name" name="name" value="Darren" >
"hidden"/>"
This commit fixes this by creating a new temporary folder for each test
method invocation.
Prior to this commit, a DataSize input string could not be parsed if it
contained any whitespace.
With this commit, a DataSize input string can contain leading, trailing,
or 'in between' whitespace. For example, the following will be parsed
to the same DataSize value.
- "1024B"
- "1024 B"
- " 1024B "
- " 1024 B "
Closes gh-28643
The previous change to the tests resulted in a failure on Windows when
using the DefaultResourceLoader by expecting an exception when no
exception is thrown.
This commit narrows the scope of the if-clause to expect an exception
only when using the FileSystemResourceLoader on Windows.
See gh-28703, gh-28746
The tests introduced in commit 9868c28c73 pass on Mac OS and Linux but
fail on Microsoft Windows.
This commit updates the tests so that they pass on MS Windows as well.
See gh-28703
Closes gh-28746
This commit fixes a NullPointerException issue in the constructor hint
predicate. Prior to this commit, a hint for a constructor was directly
looked up and dereferenced a type hint without checking if there was one
first.
This commit adds new tests for the `ApplicationContextAotGenerator`,
this time leveraging the `RuntimeHintsAgent` that checks the need for
runtime hints at runtime.
See gh-27981
In order to write proper integration tests for the `RuntimeHintsAgent`,
we need to load the java agent on the JVM and instrument test code to
check that invocations are properly recorded.
This commit adds the relevant build configuration to the
integration-tests module and adds reflection tests for the agent.
Closes gh-27981
This commit configures the `RuntimeHintsAgent` in the Spring Framework
test suite.
Instead of applying the agent to the entire test suite, and possibly
interfering with other tests, this commit adds a new custom Gradle
plugin that does the following:
* create a new test task named `"runtimeHintsTest"`
* run this task with the runtime hints java agent
* only execute tests tagged with `"RuntimeHintsTests"`
See gh-27981
This commit adds the supporting testing infrastructure using the
`RuntimeHintsAgent`. Given that the agent is loaded by the JVM running
the test suite, we can then use it to record method invocations at
runtime and check whether the prepared `RuntimeHints` match the expected
behavior.
This commit contributes the `RuntimeHintsRecorder`. With this, we can
record relevant method invocations for a given lambda, focusing on a
specific part of the code behavior. This returns a
`RuntimeHintsInvocations` instance, which is an AssertJ assert provider.
From there, we can perform assertions on the recorded invocations and
check that a given collection of hints cover the reflection, resources
and proxies needs at runtime.
This also ships the `@EnabledIfRuntimeHintsAgent` opinionated
annotation: this applies the `RuntimeHintsAgentCondition` JUnit
extension that detects whether the `RuntimeHintsAgent` is loaded by the
current JVM. Tests annotated with this will be skipped if the agent is
not present. This annotation is also tagged with a JUnit `@Tag` to
gather such tests in a specific `"RuntimeHintsTests"` test suite.
In the Spring Framework build, we have chosen to isolate such tests and
not load the agent for the main test suite ("RuntimeHintsTests" tests
are excluded from the main suite). While the agent's intent is to be as
transparent as possible, there are security and access considerations
that could interefere with other tests.
With this approach, we can then create a separate test suite and run
agent tests in a dedicated JVM.
Note that projects using this infrastructure can choose to use the
condition by itself in a custom annotation.
Here is an example of this testing infrastructure:
```
@EnabledIfRuntimeHintsAgent
class MyTestCases {
@Test
void hintsForMethodsReflectionShouldMatch() {
RuntimeHints hints = new RuntimeHints();
hints.reflection().registerType(String.class,
hint -> hint.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
RuntimeHintsInvocations invocations = RuntimeHintsRecorder.record(() -> {
Method[] methods = String.class.getMethods();
});
assertThat(invocations).match(hints);
}
}
```
See gh-27981
With the introduction of `RuntimeHints`, we can now contribute
reflection, resources and proxies hints that describe the expected
runtime behavior of the application. While this can be verified at
runtime with smoke tests, managing such tests and compiling to native
there is not very efficient.
This commit introduces the new `RuntimeHintsAgent`, a Java agent that
instruments JDK methods related to `RuntimeHints`.
It is different from the GraalVM agent, which aims at collecting all the
required hints for the runtime behavior of an application and dump those
in the expected format.
Here, the `RuntimeHintsAgent` can collect the related invocations only
for a delimited scope (typically, a lambda within a test) and later
check those against a `RuntimeHints` instance. In the case of testing
`RuntimeHintsRegistrar` implementations, the process is reversed:
instead of manually checking for registered hints in a `RuntimeHints`
instance, tests should exercise the use cases and then check that the
recorded behavior is in line with the prepared hints.
This first commit adds the agent infrastructure that collects the
invocations for all relevant JDK methods.
See gh-27981
Prior to this commit, if a cookie was added to MockHttpServletResponse,
the comment attribute was not included in the generated Set-Cookie
header. In addition, MockCookie.parse(String) did not support the
Comment attribute.
This commit addresses both of these issues.
Closes gh-28730
This is needed as GraalVM 22.2 enabled the module system when building
native-images and all plugins have to participate in it.
See gh-28624
Closes gh-28732
Given the availability of two alternatives mechanisms for URL path
matching, PathPatternParser and AntPathMatcher, and now that
parsed patterns are enabled by default, it makes sense to reduce the
proliferation of options on AbstractHandlerMapping by deprecating
shortcuts related to String path matching. Most applications rely
on Boot and on the MVC config to do all this.
See gh-28607
MockHttpServletRequest now checks the requestURI and servletPath to
check whether they imply a Servlet path mapping, which is the case
when the requestURI is longer than the contextPath + servletPath.
This is essential when parsed patterns are in use in which case the
request path is parsed taking into account only the requestURI and
the contextPath. However, if the MappingMatch indicates a match by
Servlet path, then the servletPath is also taken into account.
See gh-28607
Commit d6768ccc18 introduced a regression in the support for merging
annotation attributes in a multi-level annotation hierarchy.
This commit addresses that issue by ensuring that a merged annotation
is once again synthesized if a meta-annotation in the annotation
hierarchy declares attributes that override attributes in the target
annotation.
Closes gh-28716
As gh-28624 supports only static boolean fields, we still
need a few classes to be initialized at build time.
Such explicit configuration should be in theory avoidable,
so we will work with the GraalVM team to see if this can be
fixed, see for example
https://github.com/oracle/graal/issues/4673
for HttpStatus.
See gh-28624
When the ProtocolResolver SPI was introduced in Spring Framework 4.3,
support for protocol resolvers was added in DefaultResourceLoader's
getResource() implementation; however, GenericApplicationContext's
overridden getResource() implementation was not updated accordingly.
Prior to this commit, if a GenericApplicationContext was configured
with a custom ResourceLoader, registered protocol resolvers were
ignored.
This commit ensures that protocol resolvers are honored in
GenericApplicationContext even if a custom ResourceLoader is used.
Closes gh-28703
This commit prevents a StackOverflowError in
BindingReflectionHintsRegistrar when processing enum types
and refine related generated hints.
See gh-28683
Prior to this commit, meta-annotations were unnecessarily synthesized
when attempting to synthesize a MergedAnnotation retrieved via the
MergedAnnotations.from(AnnotatedElement, ...).get(<annotationType>) API.
This is a regression in our merged annotation support that was
introduced when the MergedAnnotations API replaced our previous support.
This commit fixes this by revising the logic in TypeMappedAnnotation's
createSynthesizedAnnotation() method so that a meta-annotation is
returned unmodified if it is not synthesizable.
This commit also updates BootstrapUtilsTests, since @BootstrapWith
should never have been synthesized, and Class#getCanonicalName() is
only used in the toString() implementation of an annotation synthesized
by Spring or normal annotations on Java 19+ (see
https://bugs.openjdk.org/browse/JDK-8281462).
Closes gh-28704
Since SpringFactoriesLoader.loadFactoryNames() will be deprecated in
gh-27954, this commit removes the use of it in the spring-test module.
Specifically, this commit removes the protected
getDefaultTestExecutionListenerClasses() and
getDefaultTestExecutionListenerClassNames() methods from
AbstractTestContextBootstrapper and replaces them with a new protected
getDefaultTestExecutionListeners() method that makes use of new APIs
introduced in SpringFactoriesLoader for 6.0.
Third-party subclasses of AbstractTestContextBootstrapper that have
overridden or used getDefaultTestExecutionListenerClasses() or
getDefaultTestExecutionListenerClassNames() will therefore need to
migrate to getDefaultTestExecutionListeners() in Spring Framework 6.0.
Closes gh-28666
This commit leverages a subset of @philwebb initial experimentation
to compute at build time the value of specific boolean static fields
in native images. This enhancement is implemented for now as a
GraalVM feature.
The goal here is to keep an optimized footprint via build time code
removal without leveraging build-time class initialization which is known
for the blocking compatibility issues it introduces due to its viral nature.
For now, the static fields initialized at build time with native are:
- NativeDetector#imageCode
- Fields with a name ending by "Present" in "org.springframework" package
typically used for classpath check with ClassUtils#isPresent
Closes gh-28624
ProblemDetail is intended to be extended with additional fields. This
commit removes its "with" methods for chained initialization to keep
it as plain as possible and avoid imposing a particular style on
subclasses.
See gh-27052
Ideally one would pass WebClient directly to HttpServiceProxyFactory,
but two need to remain decoupled. This commit adds static, shortcut
methods to WebClientAdapter to create an HttpServiceProxyFactory, thus
eliminating the step to wrap the WebClient.
This commit moves the responsibility of naming classes to the
GenerationContext. This was already largely the case before, except that
the concept of a "mainTarget" and "featureNamePrefix" was specific
to bean factory initialization contributors.
ClassNameGenerator should now be instantiated with a default target
and an optional feature name prefix. As a result, it does no longer
generate class names in the "__" package.
GeneratedClasses can now provide a new, unique, GeneratedClass or
offer a container for retrieving the same GeneratedClass based on an
identifier. This lets all contributors use this facility rather than
creating JavaFile manually. This also means that ClassNameGenerator
is no longer exposed.
Because the naming conventions are now part of the GenerationContext, it
is required to be able to retrieve a specialized version of it if a
code generation round needs to use different naming conventions. A new
withName method has been added to that effect.
Closes gh-28585
This commit refines BindingReflectionHintsRegistrar to skip
registration of hints for Object.class, primitive types and
skip members for array types.
Closes gh-28683
Align IllegalStateException with SQLException handling and propagate
the original exception.
See gh-28669
Co-authored-by: Christoph Mies <chr.mi@web.de>
Prior to this commit, Spring MVC and Spring WebFlux would not support
conditional requests with `If-Match` preconditions. As underlined in the
RFC9110 Section 13.1, those are related to the `If-None-Match`
conditions, but this time only performing requests if the resource
matches the given ETag.
This feature, and in general the `"*"` request Etag, are generally
useful to prevent "lost updates" when performing a POST/PUT request: we
want to ensure that we're updating a version with a known version or
create a new resource only if it doesn't exist already.
This commit adds `If-Match` conditional requests support and ensures
that both `If-Match` and `If-None-Match` work well with `"*"` request
ETags.
We can't rely on `checkNotModified(null)`, as the compiler can't decide
between method variants accepting an ETag `String` or a Last Modified
`long`. Instead, developers should use empty ETags `""` to signal that
no resource is known on the server side.
Closes gh-24881
Since LoggingCacheErrorHandler was only recently introduced in 5.3.16,
we have decided to completely revise its internals (protected API) in
5.3.x while retaining the current public API.
Specifically, this commit:
- introduces protected getLogger() and isLogStackTraces() methods to
improve extensibility
- revises logCacheError() to accept a Supplier<String> for lazy
resolution of error messages
Closes gh-28672
See gh-28670, gh-28648
At present, creating a LoggingCacheErrorHandler that logs stack traces
also requires supplying the logger to be used. This might be
inconvenient for some users, as it requires usage of the Commons
Logging API.
This commit simplifies creation of such as LoggingCacheErrorHandler
instance by adding a constructor that only accepts a boolean flag
indicating whether to log stack traces.
Closes gh-28670
When an overloaded method accepts additional "optional" arguments, we
typically declare the optional arguments after the required arguments.
For example, see the constructors for ClassPathResource.
This commit therefore revises the signature of the overloaded
forResourceLocation() method so that the optional ClassLoader argument
follows the required `String resourceLocation` argument.
* pr/28664:
Polish "Fix enclosing class in TypeReference for inner type arrays"
Fix enclosing class in TypeReference for inner type arrays
Closes gh-28664
As of #28620, `ResourcePatternHint` exposes its `toRegex` method.
The predicates should use it directly and mirror the exact matching
behavior.
See gh-28555
This change is done for several reasons:
- Move the logic where it is documented.
- Test it with ResourcePatternHintTests.
- Allow RuntimeHintsPredicates to leverage this logic.
Closes gh-28620
This commit adds a utility method to register a type for reflection if
it is available on the classpath. It also adds a method to register a
resource pattern if a given location is available.
Closes gh-28617
Most importantly, static @Bean methods do not expose their @Configuration class-level annotations anymore, aligned with the behavior for non-static @Bean methods.
Closes gh-28298
SQLErrorCodeSQLExceptionTranslator kicks in for user-provided sql-error-codes.xml files. It will still pick up Spring's legacy default error code mappings as well but only when triggered by a (potentially empty) user-provided file in the root of the classpath.
Closes gh-28216
Includes deprecation of NestedServletException, whereas NestedCheckedException and NestedRuntimeException remain as base classes with several convenience methods.
Closes gh-25162
Update test detecting RouterFunction beans in parent contexts to use
different bean names and avoid shadowing. Changed the fix accordingly
given that BeanProvider does detect beans in parent contexts.
See gh-28595
Move hints registration to spring-beans, where the actual behavior is
implemented. We chose not to move this to
`AutowiredAnnotationBeanPostProcessor` for now, as this would require it
to implement another AOT-related interface and add too much noise for
this.
See gh-28614
Prior to this commit, native images would dynamically check for the
presence of `jakarta.inject.*` annotations and might fail at runtime or
miss them entirely.
This change ensures that if such classes are present during the AOT
build, relevant runtime hints are registered so that these annotations
can be read at runtime.
Closes gh-28614
Prior to this commit, ObjectToObjectConverter considered the return
type of non-static `to[targetType.simpleName]()` methods but did not
consider the return type of static `valueOf(sourceType)`,
`of(sourceType)`, and `from(sourceType)` methods.
This led to scenarios in which `canConvert()` returned `true`, but a
subsequent `convert()` invocation resulted in a
ConverterNotFoundException, which violates the contract of the
converter.
This commit addresses this issue by taking into account the return type
of a static valueOf/of/from factory method when determining if the
ObjectToObjectConverter supports a particular conversion. Whereas the
existing check in `determineToMethod()` ensures that the method return
type is assignable to the `targetType`, the new check in
`determineFactoryMethod()` leniently ensures that the method return
type and `targetType` are "related" (i.e., reside in the same type
hierarchy).
Closes gh-28609
Support reflection-based serialization of parameters annotated
with @RequestBody and return values annotated with @ResponseBody.
It leverages a new BindingReflectionHintsRegistrar class that
is designed to register transitively the types usually needed
for binding and reflection-based serialization on fields,
constructors and properties. Generics are taken in account
as well.
Closes gh-28518
The `RuntimeHints` API allows to describe hints for the reflection,
proxies and resources behavior at runtime. The need for a particular
behavior can be covered by several types of hints, at different levels.
This knowledge can be important in several cases:
* before contributing additional hints, infrastructure can check if an
existing hint already covers the behavior
* this can be used in test suites and test infrastructure
This commit adds a new RuntimeHintsPredicates that generates `Predicate`
instances for testing `RuntimeHints` against a desired runtime behavior
for reflection, resources or proxies.
Closes gh-28555
We use Grafana to monitor our app via Spring's JMX exporter, and we
think it could be interesting to have at least the current queue size
for this purpose since the queue size directly affects the app memory
load. Having the queue capacity seems also interesting to set up
triggers whose values are calculated based on the maximum capacity of
the queue.
This commit introduces new getCurrentQueueSize() and getQueueCapacity()
methods in ThreadPoolTaskExecutor.
See gh-28583
Update `BeanRegistrationCodeFragments` package-private constructor
to set `codeFragments` to `this` rather than `null`. The field
is never actually read by `DefaultBeanRegistrationCodeFragments` since
all methods are overridden.
Closes gh-28578
Refine the class name logic so that the name is passed in rather
than using `ApplicationContext.getId()`. Also propagate the name
so that the generated classes use it.
See gh-28565
Update `ApplicationContextAotGenerator` so that it can generate class
names based on a `target` class and using the ID of the application
context. Prior to this commit, the generated class name was always
`__.BeanFactoryRegistrations`.
Closes gh-28565
At present, the customization of the default locale and timezone
resolution in CookieLocaleResolver and SessionLocaleResolver requires
subclassing them and overriding determineDefaultLocale and/or
determineDefaultTimeZone methods.
This commit simplifies resolution of the default locale and timezone
resolution by introducing dedicated functions for these purposes, thus
allowing customization without needing to resort to subclassing the
locale resolvers.
Closes gh-27609
This commit updates LocaleContextResolver to implement LocaleResolver
using default methods, which simplifies AbstractLocaleContextResolver
and aligns it more closely with AbstractLocaleResolver.
See gh-27609
This commit updates AcceptHeaderLocaleResolver to extend
AbstractLocaleResolver, which allows the removal of defaultLocale
managing code in AcceptHeaderLocaleResolver.
See gh-27609
To avoid unnecessary eager initialization of DataSize.PATTERN, this
commit initializes it lazily in the first invocation of DataSize.parse
by moving PATTERN to a private static nested class.
Closes gh-28560
Update the `BeanRegistrationAotContribution` interface to allow
it to customize `BeanRegistrationCodeFragments`. This change
allows us to drop the `BeanRegistrationCodeFragmentsCustomizer`
interface since an `BeanRegistrationAotProcessor` can now be
used instead.
Closes gh-28557
This commit adds a central utility to figure out if the application
must run with Ahead-Of-Time optimizations. This is mandatory for running
in a native image but can be selected on the JVM using the
"spring.aot.enabled" property.
This commit also introduces a utility that can be used to initialize a
context with generated artifacts. This represents the runtime
counterpart of ApplicationContextAotGenerator.
Closes gh-28474
Prior to this commit, the hints conditions were only supported for the
`TypeHint` case. GraalVM generally expanded this concept to all hints
and we should do the same.
Right now, only the `typeReachable` condition is available but we should
design for possible future additions.
This commit introduces a new `ConditionalHint` contract implemented by
all hints compatible with this approach. The condition information is
also used in all configuration writers as a result.
Closes gh-28126
This commit makes sure that CoroutinesUtils::invokeSuspendingFunction
treats Reactive Publisher instances the same as Kotlin Flows, i.e.
it flatmaps them.
Closes gh-27011
Attempting to name a variable in an "instanceof pattern" the same as
a field results in a Checkstyle violation similar to the following if
the "instanceof pattern matching" is located within a constructor.
Reference to instance variable 'document' needs "this.". [RequireThis]
See gh-28188
Update `BeanDefinitionMethodGeneratorFactory` to not implicitly filter
AOT processor beans if they also implement
`BeanRegistrationExcludeFilter`.
Most AOT processor beans generate code that replaces themselves, so
implicitly filtering them is the right thing to do. However, some beans
may need to perform AOT processing and still get registered when the
AOT processed application runs. These beans can now additionally
implement `BeanRegistrationExcludeFilter` to signal that they should
not be implicitly filtered.
Closes gh-28526
Update `RuntimeHintsUtils` to skip `@Reflective` annotations when
checking for `@AliasFor`. Since the `@Reflective` annotation is only
used at AOT processing time, we shouldn't need a hint for it.
See gh-28528
Prior to this commit, getPort() in HierarchicalUriComponents threw a
NumberFormatException for an invalid port supplied as a String, which
was inconsistent with exception handling elsewhere in the class as well
as within the same method.
This commit introduces a try-catch block in getPort() to consistently
throw IllegalStateExceptions for ports that cannot be parsed.
Closes gh-28521
Prior to this commit, searching for classpath resources using the
"classpath*:" resource prefix did not find all applicable resources for
applications deployed as modules -- for example, when test classes and
resources are patched into the application module automatically by
Maven Surefire.
This affected component scanning -- for example, via [@]ComponentScan --
and PathMatchingResourcePatternResolver.getResources(String) in
general.
This commit addresses this by introducing first-class support for
scanning the module path when PathMatchingResourcePatternResolver's
getResources(String) method is invoked with a location pattern using
the "classpath*:" resource prefix. Specifically, getResources(String)
first searches all modules in the boot layer, excluding system modules.
It then searches the classpath using the existing Classloader-based
algorithm and returns the combined results.
Closes gh-28506
UrlResource constructors throw checked exceptions which makes it
difficult to use them in java.util.Stream and java.util.Optional APIs
or other scenarios when a checked IOException is undesirable.
To support such use cases, this commit introduces `from(URI)` and
`from(String)` factory methods in UrlResource that throw
UncheckedIOExceptions.
Closes gh-28501
Decoding is required for non-UrlResource when the HandlerMapping is
not expected to decode the path. Encoding is the opposite.
This commit ensures correct determination of whether the HandlerMapping
is expected to have decoded the path or not that in turn depends on
whether PathPattern or PathMatcher is in use.
Closes gh-27791
This commit improves registerAnnotation to also registers the meta
annotation sources, if any. Without them, the annotation could not
be fully resolved.
See gh-28497
This commit adds a `@Reflective` annotation that can be used to declare
that the annotated element requires reflection at runtime. By default,
the annotated element is exposed but this can be customized by
specifying a dedicated `ReflectiveProcessor`.
Closes gh-28469
This commit adds a utility that takes care of registering the necessary
hints to make an annotation visible at runtime. The core framework may
create a JDK proxy if necessary, which requires specific handling.
Closes gh-28497
Prior to this commit, a ClassCastException was thrown for an Optional
return type for an @HttpExchange method. This is because the check for
an Optional return type was based on the type contained in the Optional
instead of the Optional itself.
Closes gh-28493
This reduces the package cycle between aot and annotation to an Autowired annotation reference in ConstructorOrFactoryMethodResolver, to be resolved along with gh-27920.
See gh-28414
This commit forces the resolution of all declared constructors when
registering `RuntimeHints` for Spring factories. Resolving constructors
can throw additional `NoClassDefFoundError` at runtime and during native
image compilation, if a type exposed by the constructor is missing from
the current classloader.
See gh-27955
Update `SpringFactoriesLoader` so that `null` is never used for the
cache key. Prior to this commit, calling `forDefaultResourceLocation`
with `null` and `ClassUtils.getDefaultClassLoader()` would provide
different `SpringFactoriesLoader` instances rather than making use
of a single shared cached instance.
See gh-28416
The antlr-based SpEL expression grammar file (SpringExpressions.g) was
introduced during initial development and prototyping of the Spring
Expression language; however, it was quickly abandoned in favor of a
handcrafted implementation. Consequently, it has become obsolete over
time and has never been actively maintained.
This commit therefore removes the obsolete SpEL expression grammar file.
Closes gh-28425
A static nested class does not keep an implicit reference to its
enclosing instance.
This prevents a common cause of memory leaks and uses less memory per
instance of the class.
Closes gh-28433
A static nested class does not keep an implicit reference to its
enclosing instance.
This prevents a common cause of memory leaks and uses less memory per
instance of the class.
Closes gh-28433
Update `BeanDefinitionPropertiesCodeGenerator` so that hints are
generated for property values. This restores functionality that was
inadvertently removed during refactoring.
See gh-28414
Prior to this commit, the `name` attribute in @ModelAttribute was not
supported when using WebFlux. This is because MethodParameter was used
instead of SynthesizingMethodParameter when retrieving the
@ModelAttribute annotation. In other words, @AliasFor was not honored
because the annotation was not synthesized. Consequently, only the
`value` attribute was supported in WebFlux when specifying a custom name
via @ModelAttribute.
This commit fixes this by using SynthesizingMethodParameter to retrieve
the @ModelAttribute annotation.
Closes gh-28423
Update `RegisteredBean` bean class detection to not consider
singletons. Prior to this commit, any beans that had been instantiated
could return the wrong class, especially if they were implemented using
a lambda.
See gh-28414
Add `GeneratedMethods` and `GeneratedMethod` support classes which
can be used during code generation to generation additional methods
that will ultimately be included in a `JavaFile`.
See gh-28414
Add a `GeneratedFiles` interface that can be used to add generated
source, class and resource files. An in-memory implementation is
provided for testing and a filesystem implementation is provided
to actually save the files to disk.
See gh-28414
Add resolver utilities that can be used to perform programmatic
autowiring of fields, methods, constructors and factory methods.
The resolvers are designed to work in an AOT environment and
allows the actual injection to be performed using functional
interfaces. This allows leaner images to be created since
`introspection` hints are required rather than full `invocation`
hints.
The resolvers also provide a reflection based fallback that can
used when the functional interface cannot work. For example, a
reflection based solution is required for private fields, methods
and constructors.
See gh-28414
Add a new `InstanceSupplier` interface that can be used as an
alternative to a regular bean `Supplier` when details about the
bean being supplied are required to instantiate it. The new
interface accepts a `RegisteredBean` instance which provides
access to the bean name, the bean factory creating the bean
and the bean definition.
This interface is primarily designed to allow AOT generated code
to autowire dependencies into the instance.
See gh-28414
Update the `TestCompiler` so that classes can be defined using
a `Lookup`. This update allows package-private classes to be
accessed without needing a quite so unusual classloader setup.
The `@CompileWithTargetClassAccess` should be added to any
test that needs to use `Lookup` based defines. The test will
run with a completed forked classloader so not to pollute the
main classloader.
This commit also adds some useful additional APIs.
See gh-28120
Add 'Throwable' variants of the `Consumer`, `Function`, `BiFunction` and
`Supplier` interfaces that wrap checked exceptions or allow calls to be
made that throw them.
Closes gh-28417
Update `SpringFactoriesLoader` so that it can load files from
arbitrary locations. An instance of the loader class itself is now
returned from static factory methods that accept different
locations.
The recent `ArgumentResolver` and `FailureHandler` `loadFactories`
variants are now no longer available as static methods. They are
still available as instance methods.
The `loadFactories` static method remains to provide
back-compatibility with Spring Framework 5.x
See gh-28416
* gh-28236:
Polish contribution & Support multiple quoted printable segments in Content-Disposition
Support multiple base64 segments in Content-Disposition
This commit polishes the contribution for support of multiple
base64 segments, and adds supports for multiple quoted printable
segments in Content-Disposition.
Closes gh-28236
This commit removes the dependency that the spring-web module has on
Jakarta Mail.
In FormHttpMessageConverter, a dependency on
jakarta.mail.internet.MimeUtility was replaced by existing encoding
logic in ContentDisposition.
In StandardMultipartHttpServletRequest, a dependency on the same
MimeUtility was replaced by new quoted-printable decoding logic in
ContentDisposition.
Closes gh-28392
This commit introduces the PartEvent API. PartEvents are either
- FormPartEvents, representing a form field, or
- FilePartEvents, representing a file upload.
The PartEventHttpMessageReader is a HttpMessageReader that splits
multipart data into a stream of PartEvents. Form fields generate one
FormPartEvent; file uploads produce at least one FilePartEvent. The last
element that makes up a particular part will have isLast set to true.
The PartEventHttpMessageWriter is a HttpMessageWriter that writes a
Publisher<PartEvent> to a outgoing HTTP message. This writer is
particularly useful for relaying a multipart request on the server.
Closes gh-28006
This commit adds a `getName` to `TypeReference` that provides a way to
generate the reflection target name of a type. This typically handle
primitives (omitting the `java.lang` packages) and arrays.
Closes gh-28347
Prior to this commit, we could only contribute `RuntimeHints` through
two mechanisms:
* `AotContributingBeanFactoryPostProcessor`, consdering the entire
`BeanFactory` and designed for contributing both code and hints.
* `AotContributingBeanPostProcessor`, consdering beans one by one, but
also designed for contributing both code and hints.
There are cases where libraries and applications want to contribute
`RuntimeHints` only, in a more static fashion: a dependency being
present, or a piece of infrastructure being considered by the
application context are good enough signals to contribute hints about
resources or reflection.
This commit adds the `RuntimeHintsRegistrar` contract for these cases.
Implementations can be declared as `spring.factories` and they will be
processed as soon as they're detected on the classpath. They can also be
declared with `@ImportRuntimeHints` and they will be processed if the
annotated bean definition is considered in the application context.
This annotation should be mainly used on configuration classes and on
bean methods.
```
@Configuration
@ImportRuntimeHints(CustomRuntimeHintsRegistrar.class)
public class MyConfiguration {
@Bean
@ImportRuntimeHints(OtherRuntimeHintsRegistrar.class)
public MyBean myBean() {
//...
}
}
```
Closes gh-28160
This commit makes sure that TomcatServerHttpRequest::readFromInputStream
follows the same contract as the method it overrides, and returns
AbstractListenerReadPublisher.EMPTY_BUFFER when 0 bytes are read.
See gh-28241
Previously, Graal failed to build a native image as DataSize was
unintentionally initialized at build time. This commit workarounds the
faulty assumption by flagging it as safe to initialize at build-time.
Closes gh-28328
This commit fixes a regression that added the Accept-Ranges header on
both client and server. Accept-Ranges is response header, so we now make
sure it only appears on the server side.
See gh-28291
This commit updates BasicJsonWriter to handle TypeReferences and
generate an appropriate format for a class name. Specifically, an
inner class should be separated by a dollar sign, not a dot.
Closes gh-28312
This commit introduces explicit HEAD support in Spring
MVC's ResourceHttpRequestHandler and WebFlux's ResourceWebHandler,
adding just headers but no body.
Closes gh-28291
This commit ensures that any resources created for multipart handling,
obtained via ServerWebExchange.getMultipartData(), are automatically
deleted after handling the completing the response.
Resource for parts obtained via BodyExtractors::toMultipartData and
BodyExtractors::toParts are not cleaned automatically, and
should be cleaned via Part::delete.
Closes gh-27633
Prior to this commit, the `AntPathMatcher` would inconsistently match
pattern with trailing slashes if they contain `"**"` within their
pattern.
For example `"/en/test/"` would match `"/**/test"`, but it would not
match `"/*/test"` (as it should).
This commit fixes this behavior for better consistency.
Fixes gh-27506
If we read 0 bytes, e.g. chunked encoding markup read but not the
actual data within it, don't stop reading since the server may or
may not consider it necessary to call onDataAvailable again.
Instead, we keep on reading, and although isReady likely returns
false on the next iteration, it eliminates ambiguity and ensures
the server will call onDataAvailable when more data arrives.
Closes gh-28241
Since SerializationUtils#deserialize is based on Java's serialization
mechanism, it can be the source of Remote Code Execution (RCE)
vulnerabilities.
Closes gh-28075
This commit removes the deprecated TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
search strategy from the MergedAnnotations model.
As a direct replacement for the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
search strategy, users can use the new fluent search API as follows.
MergedAnnotations mergedAnnotations =
MergedAnnotations.search(TYPE_HIERARCHY)
.withEnclosingClasses(clazz -> true) // always search enclosing classes
.from(MyClass.class);
Note, however, that users are highly encouraged to use
ClassUtils::isInnerClass, ClassUtils::isStaticClass, or a custom
predicate other than `clazz -> true`.
Closes gh-28080
Due to the deprecation of the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
search strategy (see gh-28079), this commit introduces a way for users
to provide a Predicate<Class<?>> that is used to decide when the
enclosing class for the class supplied to the predicate should be
searched.
This gives the user complete control over the "enclosing classes"
aspect of the search algorithm in MergedAnnotations.
- To achieve the same behavior as TYPE_HIERARCHY_AND_ENCLOSING_CLASSES,
a user can provide `clazz -> true` as the predicate.
- To limit the enclosing class search to inner classes, a user can
provide `ClassUtils::isInnerClass` as the predicate.
- To limit the enclosing class search to static nested classes, a user
can provide `ClassUtils::isStaticClass` as the predicate.
- For more advanced use cases, the user can provide a custom predicate.
For example, the following performs a search on MyInnerClass within the
entire type hierarchy and enclosing class hierarchy of that class.
MergedAnnotations mergedAnnotations =
MergedAnnotations.search(TYPE_HIERARCHY)
.withEnclosingClasses(ClassUtils::isInnerClass)
.from(MyInnerClass.class);
In addition, TestContextAnnotationUtils in spring-test has been
revised to use this new feature where feasible.
Closes gh-28207
This commit contains changes made because of the introduction of
HttpStatusCode. In general, methods that used to return a HttpStatus
now return HttpStatusCode instead, and methods that returned raw status
codes are now deprecated.
See gh-28214
This commit introduces HttpStatusCode, an interface implemented by
HttpStatus. Instances of HttpStatusCode are obtained via static
valueOf(int) factory method, returning a HttpStatus enum entry if
available, and a default implementation otherwise.
The underlying reason behind this change is HTTP status codes are not
enumerable, but instead range from 100-999.
Closes gh-28214
Prior to this commit, searching for merged annotations on an
AnnotatedElement in the MergedAnnotations model was only supported via
various overloaded from(...) factory methods. In addition, it was not
possible to provide a custom AnnotationFilter without providing an
instance of RepeatableContainers.
This commit introduces a fluent API for searches in MergedAnnotations
to address these issues and improve the programming model for users of
MergedAnnotations.
To begin a search, invoke MergedAnnotations.search(SearchStrategy) with
the desired search strategy. Optional configuration can then be
provided via one of the with(...) methods. To perform a search, invoke
from(AnnotatedElement), supplying the element from which to begin the
search -- for example, a Class or a Method.
For example, the following performs a search on MyClass within the
entire type hierarchy of that class while ignoring repeatable
annotations.
MergedAnnotations mergedAnnotations =
MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
.withRepeatableContainers(RepeatableContainers.none())
.from(MyClass.class);
To reuse search configuration to perform the same type of search on
multiple elements, you can save the Search instance as demonstrated in
the following example.
Search search = MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
.withRepeatableContainers(RepeatableContainers.none());
MergedAnnotations mergedAnnotations = search.from(MyClass.class);
// do something with the MergedAnnotations for MyClass
mergedAnnotations = search.from(AnotherClass.class);
// do something with the MergedAnnotations for AnotherClass
In addition, this fluent search API paves the way for introducing
support for a predicate that controls the search on enclosing classes
(gh-28207) and subsequently for completely removing the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy (gh-28080).
Closes gh-28208
The impetus for this is to be able to use ClassUtils::isStaticClass
or the existing ClassUtils::isInnerClass as a method reference for
class-based predicates that need to differentiate between static
nested types and inner classes.
See gh-28207
This commit removes Spring's custom NestedIOException and replaces its
usage with the standard IOException which has supported a root cause
since Java 6.
Closes gh-28198
With a Java 8 baseline in place for quite some time now, it no longer
makes sense to refer to features such as annotations as "Java 5
annotations".
This commit also removes old `Tiger*Tests` classes, thereby avoiding
duplicate execution of various tests.
This commit deprecates the TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search
strategy for MergedAnnotations in 6.0 M3, allowing consumers of 6.0
milestones and release candidates to provide feedback before
potentially completely removing the search strategy or providing an
alternate mechanism for achieving the same goal prior to 6.0 GA.
Closes gh-28079
See gh-28080
Adopt to R2DBC Parameter type, deprecate our own one in favor of the R2DBC type.
Add support for extensible transaction definitions and support to consume Readable and result segments.
Return Long instead of Integer in DatabaseClient update in preparation for R2DBC 1.0 changes.
This commit adds a warning to the Javadoc for the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy in
MergedAnnotations with regard to the scope of the search
algorithm.
See gh-28079
This commit implements 4 package private Json serializers
for JavaSerializationHints, ProxyHints, ReflectionHints
and ResourceHints to serialize GraalVM native JSON configuration
as documented in
https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/.
It exposes the related functionality via
NativeConfigurationGenerator which allows to generate the
relevant files on the filesystem via the
FileNativeConfigurationGenerator implementation.
The generated *-config.json files have been validated working
with GraalVM 22.0.
Closes gh-27991
* pr/28057:
Polish contribution
Provide more control over factory failure handling
Allow flexible constructor arguments in factory implementations
Closes gh-28057
Add an additional `FactoryInstantiationFailureHandler` strategy
interface to `SpringFactoriesLoader` to allows instantiation
failures to be handled on a per-factory bases.
For example, to log trace messages for only factories that can't
be created the following can be used:
FactoryInstantiationFailureHandler.logging(logger);
If no `FactoryInstantiationFailureHandler` instance is supplied
then `FactoryInstantiationFailureHandler.throwing()` is used
which provides back-compatible behavior by throwing an
`IllegalArgumentException`.
See gh-28057
Co-authored-by: Madhura Bhave <bhavem@vmware.com>
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
Update `SpringFactoriesLoader` so that factory implementation classes
can have a constructor with arguments that are resolved dynamically.
Arguments are resolved using a `ArgumentResolver` interface that is
passed to the `loadFactories` method. This strategy interface is
intentionally simple and only allows resolution based on the argument
type. A number of convenience methods are provided to allow resolvers
to be built. For example:
ArgumentResolver.of(String.class, "tests")
.and(Integer.class, 123);
Factory implementation classes must have a non-ambiguous constructor
in order to be instantiated. The `SpringFactoriesLoader` uses the same
algorithm as `BeanUtils.getResolvableConstructor`.
See gh-28057
Co-authored-by: Madhura Bhave <bhavem@vmware.com>
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
Since the Nashorn JavaScript engine was removed in Java 15, these tests
will never be run on a Java 17+ JDK which is required as of Spring
Framework 6.0.
See gh-27919
Since Spring Framework 5.3, BeanUtils.copyProperties() honors generics
in the source and target property types (see gh-24187); however, this
refinement of the contract was not properly documented prior to this
commit. In addition, the refinement can be a breaking change for users
who were relying on the previous unreliable behavior.
This commit therefore clarifies the behavior for generics support in
BeanUtils.copyProperties() and introduces a table of example matches
and mismatches when generics are involved.
Closes gh-27259
This commit updates InitDestroyBeanPostProcessor so that it contributes
init or destroy method names to the `RootBeanDefinition`. This is then
used by the generator to provide these methods to the optimized AOT
context.
Invocation of those init methods still happen using reflection so
dedicated hints are contributed for them.
Closes gh-28151
This commit makes sure that the response returned by coroutine handler
methods that return ResponseEntity<Flux> is unwrapped correctly.
Closes gh-27809
This commit updates InjectionGenerator to request a resolved attribute
with a dedicated type if multiple methods with the same name and the
same number of arguments exist. This was previously done already for
constructors and this commit harmonizes the algorithms to methods as
well
Closes gh-28154
This commit updates the generator to stop specifying a field type when
reflection is necessary, or when a reference to a field should be
retrieved as its name alone suffices.
This could trigger package protected issues if the field type is not
public.
See gh-28047
This commit fixes the algorithm used to analyze a generic parameter. If
a type in the generic signature is protected, the type is return rather
than the full signature. This makes sure that the appropriate package
is used. Previously, it would have incorrectly used the type of the
raw class.
Using a generic type for such a use case is wrong, and ProtectedElement
has been updated to expose a `Class` rather than a `ResolvableType`.
See gh-28030
This commit introduces a way to process a GenericApplicationContext
ahead of time. Components that can contribute in that phase are
invoked, and their contributions are recorded in the
GeneratedTypeContext.
This commit also expands BeanFactoryContribution so that it can exclude
bean definitions that are no longer required.
Closes gh-28150
This commit adds a way to refresh a GenericApplicationContext for ahead
of time processing: refreshForAotProcessing() processes the bean factory
up to a point where it is about to create bean instances.
MergedBeanDefinitionPostProcessor implementations are the only bean
post processors that are invoked during this phase.
Closes gh-28065
This commit adds a way for a BeanFactoryPostProcessor to participate to
AOT optimizations by contributing code that replaces its runtime
behaviour.
ConfigurationClassPostProcessor does implement this new interface and
computes a mapping of the ImportAware configuration classes. The mapping
is generated for latter reuse by ImportAwareAotBeanPostProcessor.
Closes gh-2811
Add a new unpublished `spring-core-test` module to support testing of
generated code. The module include a `TestCompiler` class which can be
used to dynamically compile generated Java code. It also include an
AssertJ friendly `SourceFile` class which uses qdox to provide targeted
assertions on specific parts of a generated source file.
See gh-28120
This commits adds an implementation that takes care of contributing
code for each bean definition in the bean factory, invoking
BeanRegistrationContributionProvider to determine the best candidate to
use.
Closes gh-28088
This commit introduces an infrastructure to contribute generated code
ahead of time to initialize a BeanFactory. Code and hints can be
contributed to a BeanFactorInitialization, with the ability to write to
other packages if necessary.
An implementation of that new interface that registers a BeanDefinition
is also included in this commit. It delegates to a
BeanInstantiationGenerator for geenerating the instance supplier that
creates the bean instance.
For corner cases, a BeanRegistrationContributionProvider can be
implemented. It allows to return a custom BeanFactoryContribution for
a particualr bean definition. This usually uses the default
implementation with a custom instance supplier.
Note that this commit adds an temporary executable resolution that is
meant to be replaced by the use of ConstructorResolver
See gh-28088
This commit extracts the logic of resolving a merged bean definition for
an inner bean to a public method so that other components can reuse it.
Closes gh-28093
This commit adds an infrastructure for code that generate types with the
need to write to another package if privileged access is required. An
abstraction around types where methods can be easily added is also
available as part of this commit.
Closes gh-28149
This commit harmonizes the use of the "generate" keyword for anything
related to code generation. Previously, there was a mix of "generate"
and "write."
See gh-28047
This commit updates AotContributingBeanPostProcessor so that it
explicitly extends from PriorityOrdered. This makes it more apparent
that AOT contributing bean post processors are meant to be invoked
early with the regular runtime, and shouldn't be post-processed
themselves.
See gh-28047
This commit polishes the contribution model where an AOT contributing
bean post processor can return a contribution, rather than a
contributor. This makes it easier to return `null` if no contribution
can be produced now that it is named this way.
See gh-28047
Attempting to create a large array in a SpEL expression can result in
an OutOfMemoryError. Although the JVM recovers from that, the error
message is not very helpful to the user.
This commit improves the diagnostics in SpEL for large array creation
by throwing a SpelEvaluationException with a meaningful error message
in order to improve diagnostics for the user.
Closes gh-28145
Prior to this commit, the ResponseSpec::expectBody extension function
returned a special KotlinBodySpec, due to
https://youtrack.jetbrains.com/issue/KT-5464.
Now that KT-5464 has been fixed in Kotlin 1.6, we have no need for
KotlinBodySpec, so this commit replaces it with a extension function
that returns the Java BodySpec.
Closes gh-28144
This commit improves the documentation for test execution events,
especially with regard to the fact that, by default, a
BeforeTestClassEvent is not published for the first test class using a
particular ApplicationContext.
This commit also introduces tests that verify the default behavior and
the ability to change the default behavior with a custom
TestExecutionListener that eagerly loads the context.
Closes gh-27757
Prior to this commit, there was no way to configure type-safe rollback
rules for transactions.
Even though a rollback rule could be defined using a Class reference
via the `rollbackFor` and `noRollbackFor` attributes in @Transactional,
those Class references got converted to Strings (as the fully qualified
class names of the exception types) in RollbackRuleAttribute which then
applied a pattern-based matching algorithm as if the Class references
had been supplied as Strings/patterns to begin with, thereby losing the
type information.
Pattern-based rollback rules suffer from the following three categories
of unintentional matches.
- identically named exceptions in different packages when the pattern
does not include the package name -- for example,
example.client.WebException and example.server.WebException both
match against a "WebException" pattern.
- similarly named exceptions in the same package when a given exception
name starts with the name of another exception -- for example,
example.BusinessException and example.BusinessExceptionWithDetails
both match against an "example.BusinessException" pattern.
- nested exceptions when an exception type is declared in another
exception -- for example, example.BusinessException and
example.BusinessException$NestedException both match against an
"example.BusinessException" pattern.
This commit prevents the latter two categories of unintentional matches
for rollback rules defined using a Class reference by storing the
exceptionType in RollbackRuleAttribute and using that type in the
implementation of RollbackRuleAttribute.getDepth(Class, int), resulting
in type-safe rollback rules whenever the `rollbackFor` and
`noRollbackFor` attributes in `@Transactional` are used.
Note that the first category of unintentional matches never applied to
rollback rules created from a Class reference since the fully qualified
name of a Class reference always includes the package name.
Closes gh-28098
This commit introduces Javadoc to explain the difference between
init/destroy method names when such methods are private, namely that a
private method is registered via its qualified method name; whereas, a
non-private method is registered via its simple name.
See gh-28083
Prior to this commit, `AsyncRestTemplate` would log errors (including
simple 404s) with WARN level. Such errors are quite common and should
not clutter logs.
This commit aligns the logging strategy with RestTemplate, using the
DEBUG level for such cases.
Fixes gh-28049
DefaultHandlerExceptionResolver now supports ErrorResponse exceptions
and can map them to HTTP status and headers of the response. This
includes not only exceptions from spring-web, but also any other
exception that implements ErrorResponse.
ResponseEntityExceptionHandler is updated along the same lines, now
also handling any ErrorResponseException. It can be used it for
RFC 7807 support for Spring MVC's own exceptions.
See gh-27052
All Spring MVC exceptions from spring-web, now implement ErrorResponse
and expose HTTP error response information, including an RFC 7807 body.
See gh-27052
ErrorResponse represents a complete error response with status, headers,
and an RFC 7807 ProblemDetail body.
ErrorResponseException implements ErrorResponse and is usable on its
own or as a base class. ResponseStatusException extends
ErrorResponseException and now also supports RFC 7807 and so does its
sub-hierarchy.
ErrorResponse can be returned from `@ExceptionHandler` methods and is
mapped to ResponseEntity.
See gh-27052
ProblemDetail is a representation of an RFC 7807 "problem", and this
commits adds support for it in Spring MVC and WebFlux as a return value
from `@ExceptionHandler` methods, optionally wrapped with
ResponseEntity for headers.
See gh-27052
Before this commit, CronField.Type::rollForward added temporal units
to reach the higher order field. This caused issues with DST, where
the added amount of hours was either too small or too large.
This commit refactors the implementation so that it now adds one to the
higher order field, and reset the current field to the minimum value.
Closes gh-28095
The TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy for
MergedAnnotations was originally introduced to support @Nested test
classes in JUnit Jupiter (see #23378).
However, while implementing #19930, we determined that the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy unfortunately
could not be used since it does not allow the user to control when to
recurse up the enclosing class hierarchy. For example, this search
strategy will automatically search on enclosing classes for static
nested classes as well as for inner classes, when the user probably
only wants one such category of "enclosing class" to be searched.
Consequently, TestContextAnnotationUtils was introduced in the Spring
TestContext Framework to address the shortcomings of the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy.
Since this search strategy is unlikely to be useful to general users,
the team has decided to deprecate this search strategy in Spring
Framework 5.3.x and remove it in 6.0.
Closes gh-28079
Prior to this commit, SpEL was able to recover from an error that
occurred while running a CompiledExpression; however, SpEL was not able
to recover from an error that occurred while compiling the expression
(such as a java.lang.VerifyError). The latter can occur when multiple
threads concurrently change types involved in the expression, such as
the concrete type of a custom variable registered via
EvaluationContext.setVariable(...), which can result in SpEL generating
invalid bytecode.
This commit addresses this issue by catching exceptions thrown while
compiling an expression and updating the `failedAttempts` and
`interpretedCount` counters accordingly. If an exception is caught
while operating in SpelCompilerMode.IMMEDIATE mode, the exception will
be propagated via a SpelEvaluationException with a new
SpelMessage.EXCEPTION_COMPILING_EXPRESSION error category.
Closes gh-28043
Update the pluginManagement repositories used by Grade to include
`mavenCentral()` since `gradlePluginPortal()` has been suffering
from timeouts recently.
Prior to this commit, it was not clear that a configured base URI would
not be applied when invoking uri(URI).
This commit adds a note to the Javadoc to clarify that behavior.
Closes gh-28058
Update the pluginManagement repositories used by Grade to include
`mavenCentral()` since `gradlePluginPortal()` has been suffering
from timeouts recently.
SocketUtils was introduced in Spring Framework 4.0, primarily to assist
in writing integration tests which start an external server on an
available random port. However, these utilities make no guarantee about
the subsequent availability of a given port and are therefore
unreliable. Instead of using SocketUtils to find an available local
port for a server, it is recommended that users rely on a server's
ability to start on a random port that it selects or is assigned by the
operating system. To interact with that server, the user should query
the server for the port it is currently using.
SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0.
Closes gh-28052
In 3ec612aaf8, I accidentally removed tests that verified support for
non-synthesizable merged annotations for recursive annotations in
Kotlin.
This commit reinstates those non-synthesizable tests while retaining
the synthesizable tests.
This commit introduces an optional interface that a BeanPostProcessor
can implement to opt-in for providing a generated code equivalent of
what it does with a regular runtime.
This commit has a first implementation of this interface with
AutowiredAnnotationBeanPostProcessor replacing its processing of
autowired annotations by generated code.
Closes gh-27921
This commit improves how protected access analysis operates. Rather than
providing a static boolean, a function callback for the member to
analyse is used. This permits to change the decision whether reflection
can be used, or if the return type is assigned.
Both of those are already applicable, with InjectionGenerator relying
on reflection for private fields, and DefaultBeanInstanceGenerator
assigning the bean instance if additional contributors are present.
This commit also moves the logic of computing the options where the code
is actually generated.
See gh-28030
This commit provides the necessary infrastructure to let components
contribute statements that are used to fully instantiate a bean
instance.
To ease code generation, a dedicated infrastructure to register bean
definition is provided in the o.s.beans.factory.generator package.
BeanDefinitionRegistrar offers a builder style API that provides a way
to hide how injected elements are resolved at runtime and let
contributors provide code that may throw a checked exception.
BeanInstanceContributor is the interface that components can implement
to contribute to a bean instance setup. DefaultBeanInstanceGenerator
generates, for a particular bean definition, the necessary statements
to instantiate a bean.
Closes gh-28047
Kotlin currently only supports JDK17 language level, which is our
minimum requirement so far.
This commit simplifies the toolchain setup until this is needed again.
See 303e363adf
This commit upgrades the CI pipeline with the following:
* replace JDK16 with JDK17 as build variant
* upgrade all JDK versions
* replace docker-image with registry-image resource for CI image
Although Java does not allow the definition of recursive annotations,
Kotlin does, and prior to this commit an attempt to synthesize a
merged annotation using the MergedAnnotation API resulted in a
StackOverflowError if there was a recursive cycle in the annotation
definitions.
This commit addresses this issue by tracking which annotations have
already been visited and short circuits the recursive algorithm if a
cycle is detected.
Closes gh-28012
Although the initial report in gh-28015 only covered inconsistencies
for arrays and strings in the toString() implementations for
annotations between the JDK (after Java 9) and Spring, it has since
come to our attention that there was further room for improvement.
This commit therefore addresses the following in toString() output for
synthesized annotations.
- characters are now wrapped in single quotes.
- bytes are now properly formatted as "(byte) 0x##".
- long, float, and double values are now appended with "L", "f", and
"d", respectively. The use of lowercase for "f" and "d" is solely to
align with the choice made by the JDK team.
However, this commit does not address the following issues which we may
choose to address at a later point in time.
- non-ASCII, non-visible, and non-printable characters within a
character or String literal are not escaped.
- formatting for float and double values does not take into account
whether a value is not a number (NaN) or infinite.
Closes gh-28015
This commit adds an API that lets individual components contribute code,
runtime hints, and protected access information. This ease the cases
where code need to be written in a privileged package if necessary and
let contributors provide hints for the code they generate.
Closes gh-28030
This commit repackages the Javapoet library into spring-core so that it
can be used by the AOT engine without requiring a specific version.
Closes gh-27828
Since the introduction of synthesized annotation support in Spring
Framework 4.2 (a.k.a., merged annotations), the toString()
implementation attempted to align with the formatting used by the JDK
itself. However, Class annotation attributes were formatted using
Class#getName in Spring; whereas, the JDK used Class#toString up until
JDK 9.
In addition, JDK 9 introduced new formatting for toString() for
annotations, apparently intended to align with the syntax used in the
source code declaration of the annotation. However, JDK 9+ formats enum
annotation attributes using Enum#toString instead of Enum#name, which
can lead to issues if toString() is overridden in an enum.
This commit updates the formatting used for synthesized annotations by
ensuring that toString() generates a string that is compatible with the
syntax of the originating source code, going beyond the changes made in
JDK 9 by using Enum#name instead of Enum#toString.
Closes gh-28015
Prior to this commit, WebTestClient only supported "lenient" comparison
of the expected JSON body.
This commit introduces an overloaded variant of `json()` in the
BodyContentSpec that accepts an additional boolean flag to specify
whether a "strict" comparison should be performed.
This new feature is analogous to the existing support in MockMvc.
Closes gh-27993
Prior to this commit, if AOP proxy generation was configured with
proxyTargetClass=true (which is the default behavior in recent versions
of Spring Boot), beans implemented as lambda expressions or method
references could not be proxied with CGLIB on Java 16 or higher without
specifying `--add-opens java.base/java.lang=ALL-UNNAMED`.
This commit addresses this shortcoming by ensuring that beans
implemented as lambda expressions or method references are always
proxied using a JDK dynamic proxy even if proxyTargetClass=true.
Closes gh-27971
Prior to this commit, the QuartzCronField::weekdayNearestTo would elapse
until the next month before checking if the current day matched.
After this commit, the current day is checked before we elapse until
the next month.
Closes gh-27966
In a small minority of cases, the multipart boundary can spread across
three incoming buffers.
Prior to this commit, MultipartParser.BodyState only supported two
buffers. If the boundary is spread across three buffers, the first
buffer of the three is sent as a whole, even though it contains the
first bytes of the boundary.
This commit fixes this bug, by enqueuing all prior buffers in a queue,
and emitting the ones that cannot contain boundary bytes.
Closes gh-27939
This commit provides an API to record the need for reflection,
resources, serialization, and proxies so that the runtime can be
optimized accordingly.
`RuntimeHints` provides an entry point to register the following:
* Reflection hints: individual elements of a type can be defined, as
well as a predefined categories (identified by the `MemberCategory`
enum). A method or constructor hint can refine whether the executable
should only be introspected or also invoked.
* Resource hints: patterns using includes/excludes identify the
resources to include at runtime. Resource bundles are also supported.
* Java Serialization hints: types that use java serialization can be
registered.
* Proxy hints: both interfaces-based (JDK) proxy and class-based proxy
can be defined.
This commit also introduces a `TypeReference` abstraction that permits
to record hints for types that are not available on the classpath, or
not compiled yet (generated code).
Closes gh-27829
Prior to this commit, the USER_DECLARED_METHODS MethodFilter in
ReflectionUtils did not actually filter methods declared in
java.lang.Object as stated in its Javadoc.
Consequently, if ReflectionUtils.doWithMethods was invoked with
USER_DECLARED_METHODS and Object.class as the class to introspect, all
non-bridge non-synthetic methods declared in java.lang.Object were
passed to the supplied MethodCallback, which breaks the contract of
USER_DECLARED_METHODS.
In addition, if USER_DECLARED_METHODS was composed with a custom
MethodFilter using `USER_DECLARED_METHODS.and(<custom MethodFilter>)`,
that composed method filter allowed all non-bridge non-synthetic
methods declared in java.lang.Object to be passed to the supplied
MethodCallback, which also breaks the contract of
USER_DECLARED_METHODS. This behavior resulted in regressions in code
that had previously used USER_DECLARED_METHODS by itself and then began
using USER_DECLARED_METHODS in a composed filter. For example, since
commit c419ea7ba7 ReflectiveAspectJAdvisorFactory has incorrectly
processed methods in java.lang.Object as candidates for advice methods.
This commit fixes this bug and associated regressions by ensuring that
USER_DECLARED_METHODS actually filters methods declared in
java.lang.Object. In addition, ReflectionUtils.doWithMethods now aborts
its search algorithm early if invoked with the USER_DECLARED_METHODS
filter and Object.class as the class to introspect.
Closes gh-27970
Prior to this commit, we only (indirectly) configured external Javadoc
links for types in the javax.annotation package for JSR 250, since
those types are part of Java 8 SE. However, an external Javadoc link
for types from JSR 305 was not configured.
To address this issue, this commit now configures an external Javadoc
link for JSR 305 types. However, the external Javadoc link for JSR 305
must be configured last to ensure that types from JSR 250 (such as
@PostConstruct) are still supported. This is due to the fact that JSR
250 and JSR 305 both define types in javax.annotation, which results in
a split package, and the javadoc tool does not support split packages
across multiple external Javadoc sites. Instead, the Javadoc tool
iterates over all external links, and the first external site that
claims to support a given package (via the package-list file) wins.
This means:
- Javadoc for JSR 250 annotations is fully supported.
- Javadoc for JSR 305 annotations in the javax.annotation package will
continue to result in a 404 (page not found) error.
- Javadoc for JSR 305 annotations in the javax.annotation.meta package
is fully supported.
For Spring Framework 6.0, the Javadoc for JSR 250 types in
jakarta.annotation package is served from the JBoss Application Server
Javadoc site instead of from Oracle's Java SE documentation site, since
JSR 250 annotations are no longer included in Java SE.
Closes gh-27904
This commit switches from CGLIB-based proxies to JDK dynamic proxies
for AOP and scoped-bean tests, in order to be able to run tests in the
Eclipse IDE without special Run Configuration setup for the Java module
system.
This commit also simplifies the loading of beans defined with the Groovy
DSL.
See gh-27945
Prior to this commit, GroovyDynamicElementReader was implemented in
Groovy, which required that developers have Groovy language support
installed and configured in their IDEs.
This commit ports GroovyDynamicElementReader from Groovy to Java,
making the compilation much simpler and allowing developers to open the
project in Eclipse or VSCode (or other IDEs without Groovy support)
without compiler errors.
This commit also converts related tests from Groovy to Java.
Closes gh-27945
Prior to this commit, if a PropertySourcesPlaceholderConfigurer bean
was configured with its ignoreUnresolvablePlaceholders flag set to
true, unresolvable placeholders in an @Value annotation were not
ignored, resulting in a BeanCreationException for the bean using @Value.
For example, given a property declared as `my.app.var = ${var}` without
a corresponding `var` property declared, an attempt to resolve
`@Value("${my.app.var}")` resulted in the following exception.
java.lang.IllegalArgumentException: Could not resolve placeholder 'var' in value "${var}"
This commit fixes this by modifying
PropertySourcesPlaceholderConfigurer's postProcessBeanFactory(...)
method so that a local PropertyResolver is created if the
ignoreUnresolvablePlaceholders flag is set to true. The local
PropertyResolver then enforces that flag, since the Environment in the
ApplicationContext is most likely not configured with
ignoreUnresolvablePlaceholders set to true.
Closes gh-27947
Commit 6316a35 introduced a regression for property names starting with
multiple uppercase letters (such as setEMail(...)).
This commit fixes that regression and includes an additional test to
cover this case.
See gh-27929
Closes gh-27941
This commit introduces a dedicated (disabled) transferToWithUndertow()
test method to simplify debugging of transferTo issues with Undertow.
See gh-25310
Closes gh-27908
Instead of simply returning prematurely and allowing the tests to be
marked as SUCCESS, this commit uses a failed assumption to abort the
the trasferTo tests for Undertow, resulting in the parameterized test
invocation properly being marked as ABORTED.
See gh-25310
Prior to this commit, XmlValidationModeDetector did not properly parse
all categories of comments (described below). When such categories of
comments were encountered XmlValidationModeDetector may have
incorrectly detected that an XML file used a DTD when it used an XSD,
or vice versa.
This commit revises the parsing algorithm in XmlValidationModeDetector
so that multi-line comments and multiple comments on a single line are
properly recognized.
Specifically, with this commit the following categories of comments are
now handled properly.
- Multiple comments on a single line
- Multi-line comment: beginning on one line and then ending on another
line with an additional comment following on that same line.
- Multi-line comment: beginning at the end of XML content on one line
and then spanning multiple lines.
Closes gh-27915
Prior to this commit, the `apiDiff` custom Gradle task would only use
the configured repositories in the build to generated the API diff
report. This causes issues when the report has to be generated against a
previous milestone: the Spring Framework build only relies on Maven
Central and a specific `libs-spring-framework-build` repository for
building the project. In this case, the task cannot resolve the previous
milestone artifacts to generate the report.
This commit improves the `ApiDiffPlugin` to automatically add the Spring
Milestone repository to the root project configuration when the task is
executed.
Fixes gh-27928
Prior to this commit, the PrintingResultHandler in MockMvc -- typically
invoked via .andDo(print()) -- printed an `application/json` response
body using the default encoding (ISO-8859-1), which resulted in UTF-8
characters being garbled.
Since an `application/json` response is implicitly encoded using UTF-8,
the PrintingResultHandler now infers UTF-8 encoding for such response
bodies.
Closes gh-27926
The failing test is for Apache HttpComponents where we cannot apply the
Content-Length together with other headers, and must pass it instead
explicitly to ReactiveEntityProducer when writing at which point it gets
set in the native headers.
Closes gh-27768
Prior to this commit, our BlockHound integration tests were disabled
after the migration to a JDK 17 baseline since the build now always
runs on JDK 14 or higher.
To re-enable the tests we now supply the deprecated
-XX:+AllowRedefinitionToAddDeleteMethods command-line argument to the JVM
for tests in the Gradle build. Users can also configure this manually
within an IDE to run SpringCoreBlockHoundIntegrationTests.
If that command-line argument is removed from the JVM at some point in
the future, we will need to investigate an alternative solution.
See https://github.com/reactor/BlockHound/issues/33 for details.
In BridgeMethodResolver#isBridgedCandidateFor, candidateMethod is never
not bridged, so it's unnecessary to judge whether candidateMethod and
bridgeMethod are the same.
Closes gh-27862
NettyHeadersAdapter::putAll uses HttpHeaders::add, which does not
overwrite existing headers. putAll should use HttpHeaders::set instead,
just like NettyHeadersAdapter::put does.
Closes gh-27887
Prior to this commit, the error message generated for a mismatched
number of generics did not include the information about the class in
question.
This commit improves the error message by providing more context,
specifically the result of invoking toGenericString() on the class.
For example, instead of throwing an IllegalArgumentException with the
error message "Mismatched number of generics specified", the error
message would now be "Mismatched number of generics specified for
public abstract interface java.util.Map<K,V>".
Closes gh-27847
@hpoettker made me aware of the ModeEnum in H2 that allows the
parameterized test to be simplified, which was the primary impetus for
this commit.
See gh-27870
The test case is intended to be for the method 'withRootObject()', but
actually it's copied from the previous test method that does not use
'withRootObject()'.
This commit fixes the propertyReadWriteWithRootObject() test method in
PropertyAccessTests.
Closes gh-27905
Commit ed4e2289cd introduced support for H2 2.0.x but did not upgrade
the H2 dependency.
This commit upgrades the H2 dependency to version 2.0.206 but also
adds an explicit test dependency on version 1.4.200 in spring-r2dbc,
since r2dbc-h2 does not yet support H2 2.0.x.
Once https://github.com/r2dbc/r2dbc-h2/pull/204 has been included in a
released version of r2dbc-h2 we will be able to upgrade spring-r2dbc's
test dependency on the H2 database to 2.0.x as well.
See gh-27870
See gh-27902
Prior to this commit, H2SequenceMaxValueIncrementer only supported H2
database 1.4.
This commit updates H2SequenceMaxValueIncrementer's getSequenceQuery()
method so that the syntax used supports version 1.4 and 2.0 of the H2
database.
This commit also updates several test schemas so that they work with H2
1.4 and 2.0 as well as HSQL.
Closes gh-27870
The EntityManager interface does not implement AutoCloseable until
JPA 3.1.
This commit therefore partially reverts 189e1afc6e so that the
example code compiles with the supported JPA version.
See gh-22269
Closes gh-27886
Where unfeasible, this commit adds inline comments to explain why
try-with-resources must not be used in certain scenarios. The purpose
of the comments is to avoid accidental conversion to try-with-resources
at a later date.
Closes gh-27823
This helps to reduce noise in the "Problems" view by not displaying
warnings resulting from @SuppressWarnings tokens that Eclipse does not
understand -- for example, tokens supported by IntelliJ IDEA or other
tools.
Although this commit only applies to test classes, it serves to reduce
the noise when searching for undesirable usage of StringBuffer in
production code.
With JDK 9, java.util.regex.Matcher received overloaded variants of
appendReplacement() and appendTail() that accept a StringBuilder,
allowing us to replace the use of StringBuffer with StringBuilder.
Closes gh-27884
With JDK 9, java.util.regex.Matcher received overloaded variants of
appendReplacement() and appendTail() that accept a StringBuilder,
allowing us to replace the use of StringBuffer with StringBuilder.
Closes gh-27822
The getBeanFactory() method (which is deprecated since Spring Framework
5.3.15) has been obsolete for more than 13 years since it was superseded
by the getRegistry() method in the BeanDefinitionReader interface.
Closes gh-27875
The getBeanFactory() method has been obsolete for more than 13 years
since it was superseded by the getRegistry() method in the
BeanDefinitionReader interface.
Closes gh-27875
This commit replaces the use of Collections.unmodifiableList/Set/Map
with the corresponding 'of(...)' factory methods introduced in Java 9.
Closes gh-27824
* pr/27848:
Polish "Add Javadoc since to new PayloadApplicationEvent constructor"
Add Javadoc since to new PayloadApplicationEvent constructor
Closes gh-27848
This commit adds default methods to CachingConfigurer and
JCacheConfigurer and removes the reference to their respective support
classes as they are now irrelevant.
Closes gh-27811
Prior to this commit, if a single null value was passed to a method with
a varargs array of type java.util.Optional, that null value was passed
unmodified. On the contrary, a null passed with additional values to
such a method resulted in the null being converted to Optional.empty().
This commit ensures that a single null value is also converted to
Optional.empty() for such SpEL expressions.
Closes gh-27795
A regression was introduced in gh-27582. Specifically, when null is
supplied as the single argument for a varargs parameter in a method or
function in a SpEL expression, ReflectionHelper currently throws a
NullPointerException instead of leaving the null value unchanged.
This commit fixes this regression.
Closes gh-27719
This commits deprecates
- StringUtils::trimWhitespace in favor of String::strip
- StringUtils::trimLeadingWhitespace in favor of String::stripLeading
- StringUtils::trimTrailingWhitespace in favor of String::stripTrailing
Closes gh-27769
This commit makes it possible to customize 404 responses generated by
RouterFunctionWebHandler, by throwing an ResponseStatusException
instead of returning a standard 404 response.
See gh-25358
* pr/24599:
Polish "Add support for explicit generic type in PayloadApplicationEvent"
Add support for explicit generic type in PayloadApplicationEvent
Closes gh-24599
This commit refactors HttpMethod from a Java enum into a class. The
underlying reason being that HTTP methods are not enumerable, but
instead an open range and not limited to the predefined values in the
specifications.
Closes gh-27697
Prior to this commit, ServerResponse headers would only be written if
there were no existing headers with the same name, thus making it
impossible to overwrite existing headers.
With the changes in this commit, headers are always written.
Closes gh-27741
The current implementation suggests that the request's headers are not
expected to change. Hence, it's not necessary to copy them.
Furthermore, it might be costly to do so if there are many headers.
Instead, cache only the request's header names for method getHeaderNames.
Methods getHeader and getHeaders delegate to the respective methods of
request if the header name is not in FORWARDED_HEADER_NAMES. Otherwise,
they return null or an empty Enumeration respectively.
See gh-27466
Prior to this commit, the SpEL relational operators for comparison
would have the following problem:
* their implementation would claim that incompatible types
could be compared and later fail during comparison
* not delegate the comparison to the actual `TypeComparator`
implementation but rely on operator specifics
This commit ensures that the `TypeComparator` implementation is used for
both `canCompare` and `compare` calls in the operators.
See gh-1581
* pr/2030:
Polish "Clarify behaviour of AnnotationBeanNameGenerator with acronyms"
Clarify behaviour of AnnotationBeanNameGenerator with acronyms
Closes gh-2030
Name transformation is delegated to Introspector#decapitalize, which
states "but in the (unusual) special case when there is more than one
character and both the first and second characters are upper case, we
leave it alone.". This commit clarifies this behavior.
See gh-2030
The default documentation does not mention xxx*yyy pattern matching,
which is, however, supported by PatternMatchUtils. Such a pattern
can be useful for matching nested properties in all elements of a
collection, e.g. property[*].nestedProperty.
See gh-699
This commit makes several changes to MimeType and MediaType
related to the topic of specificity.
This commit deprecates the MimeType and MediaType Comparators.
Comparators require a transitive relationship, and the desired order for
these types is not transitive (see #27488).
Instead, this commit introduces two new MimeType methods: isMoreSpecific
and isLessSpecific, both of which return booleans. MediaType overrides
these methods to include the quality factor (q) in the comparison.
All MediaType sorting methods have been deprecated in favor of
MimeTypeUtils::sortBySpecificity. This sorting method now uses
MimeType::isLessSpecific in combination a bubble sort algorithm (which
does not require a transitive compare function).
Closes gh-27580
This commit ensures that only HTML references of length <
MAX_REFERENCE_SIZE are considered as potential references. This check is
possible because reference longer than 10 digits are out of bounds for
Integers.
Closes gh-1249
This commit changes DefaultClientResponse::createException to use
the ByteArrayDecoder, instead of converting to DataBuffers and
turning these into a byte array.
Closes gh-27666
Since Spring Framework 6 uses JDK 17 for its baseline, we can make use
of toList() and toUnmodifiableSet() which were introduced in JDK 16 and
JDK 10, respectively.
Closes gh-27618
This commit fixes a bug in the DefaultPartHttpMessageReader, in the
check for exceeding the maximum header size. Before this commit, the
entire buffer size was considered, thus triggering an exception even
though the max header limit was not exceeded. After this commit, we only
consider the size up until the end-of-header mark (CRLFCRLF).
Furthermore, this commit increases the default maximum header size to
10k, the same default as Commons File upload.
Closes gh-27612
This commit introduces UnmodifiableMultiValueMap, an immutable wrapper
around a MultiValueMap, similar to what is returned by
Collections.unmodifiable*.
CollectionUtils::unmodifiableMultiValueMap now returns
UnmodifiableMultiValueMap.
Closes gh-27608
This commit adds a new JDK 18 variant to the CI build image and
configures a JDK18 build (sources compiled with JDK17, tests compiled
and run with JDK18) to the CI pipeline.
Closes gh-27607
Prior to this commit, Spring's SchedulerFactoryBean always set the
"org.quartz.jobStore.class" property to LocalDataSourceJobStore even if
the user had already specified a custom JobStore implementation via the
Quartz properties file or Properties object, thereby effectively
ignoring the user configuration.
This commit addresses this by configuring Quartz to use Spring's
LocalDataSourceJobStore only if a JobStore has not already been
specified via user configuration.
Closes gh-27560
Prior to this commit, UndertowHeadersAdapter's remove() method violated
the java.util.Map contract by always returning null.
This commit fixes this by returning the previous list stored under the
specified key, and otherwise returning null if no previous value was
present.
Closes gh-27592
Prior to this commit, if a SpEL expression invoked a method or
registered function that declares a String varargs argument, there were
sometimes issues with converting the input arguments into the varargs
array argument. Specifically, if the expression supplied a single
String argument containing a comma for the varargs (such as "a,b"),
SpEL's ReflectionHelper.convertArguments() method incorrectly converted
that single String to an array via the ConversionService, which
indirectly converted that String using the StringToArrayConverter,
which converts a comma-delimited String to an array. Thus, "a,b"
effectively got converted to a two-dimensional array ["a", "b"] instead
of simply ["a,b"].
This commit fixes this bug by avoiding use of the TypeConverter and
ConversionService for single arguments supplied as varargs when the
single argument's type matches the varargs array component type.
Closes gh-27582
Prior to this commit, third parties using @ComponentScan's @Filter
annotation had to implement their own parsing for @Filter
AnnotationAttributes as well as instantiation of the corresponding
TypeFilters. In such cases the various *Aware callbacks
(BeanFactoryAware, EnvironmentAware, etc.) should also be supported.
This commit therefore extracts a new public TypeFilterUtils class from
ComponentScanAnnotationParser so that third parties can benefit from
consistent TypeFilter creation from @ComponentScan @Filter annotations.
Closes gh-27553
The custom stylesheet used with JDK 8 no longer works with JDK 17.
Thus in order to make the generated Javadoc usable, we are disabling
the custom stylesheet for the time being.
See gh-27496
The fix made for gh-27488 resulted in a change of the default order
of codecs. This commit reverts these changes, so that the previous
order is restored.
Closes gh-27573
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- try with resources
- multi-catch
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- multi-catch
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- try with resources
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- for-each loop
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
This commit also makes use of java.lang.String.repeat(int) in OptMultiply.
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- Comparator.comparing
- convert to switch expression
This has only been applied to `src/main/java`.
This commit also applies additional clean-up tasks such as the following.
- final fields
- diamond operator (<>) for anonymous inner classes
- Comparator.comparing
This has only been applied to `src/main/java`.
This commit fixes the Javadoc in all queryForObject(...) methods in
JdbcOperations and NamedParameterJdbcOperations regarding what kinds of
exceptions are thrown under which conditions.
Closes gh-27559
Prior to this commit, DatabasePopulatorUtils.execute(...) did not
perform a commit for the current Connection. This works for most use
cases; however, when DatabasePopulatorUtils is used to execute
initialization scripts without a managed transaction -- for example,
via a DataSourceInitializer configured as a bean in the
ApplicationContext or via Spring Boot configuration in
application.properties -- if the underlying database is configured with
auto-commit=false, the results of executing the SQL scripts are not
committed to the database which can lead to data being silently lost.
This commit addresses this issue by committing the Connection for the
supplied DataSource if the connection is not configured for auto-commit
and is not transactional. Existing use cases running with a managed
transaction should therefore not be affected by this change.
Closes gh-27008
ResponseEntityResultHandler nests correctly, only once for the ResponseEntity,
when there is a Mono adapted from a Kotlin Continuation.
Closes gh-27292
In our application we use XML context and <cache:annotation-driven />
declaration. Also we disable bean definition duplication by setting
GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in an
ApplicationContextInitializer. This combination leads to a
BeanDefinitionOverrideException because the
DefaultJCacheOperationSource bean is registered twice.
- once for: parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
- once for: parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
This commit refactors JCacheCachingConfigurer.registerCacheAspect(...)
so that the JCacheOperationSource bean is registered only once.
Closes gh-27499
Prior to this commit, the default CacheAwareContextLoaderDelegate could
be configured by extending AbstractTestContextBootstrapper and
overriding getCacheAwareContextLoaderDelegate(); however, this required
that the user configure the custom TestContextBootstrapper via
@BootstrapWith.
This commit introduces a new
"spring.test.context.default.CacheAwareContextLoaderDelegate" property
that can be configured via a JVM system property or via the
SpringProperties mechanism. BootstrapUtils uses this new property to
load the default CacheAwareContextLoaderDelegate. If the property is
not defined, BootstrapUtils will fall back to creating a
DefaultCacheAwareContextLoaderDelegate as it did previously.
This allows third parties to configure the default
CacheAwareContextLoaderDelegate transparently for the user -- for
example, to intercept context loading in order to load the context in a
different manner -- for example, to make use of ahead of time (AOT)
techniques for implementing a different type of ApplicationContext at
build time.
Closes gh-27540
This commit makes sure that the Reactor context from a given mono or
flux is propagated to the Flux returned by a FluxSink. This change
affects both DataBufferUtils::write and internal classes used by the
DefaultPartHttpMessageReader.
Closes gh-27517
Due to an SSL/TLS issue with hamcrest.org, the Dokka task fails with the
following.
> Failed to download package-list from https://hamcrest.org/JavaHamcrest/javadoc/2.1/package-list,
> this might suggest that remote resource is not available, module is
> empty or dokka output got corrupted
See: https://github.com/hamcrest/JavaHamcrest/issues/280
As a workaround, this commit switches to javadoc.io to reference the
Hamcrest Javadoc APIs.
No need to log the full exception for a resolved exception, and as the
comment suggests that it mirrors Spring MVC equivalent, which also
logs the message only.
PR gh-24470 introduced a regression for Android users by no longer
escaping closing curly braces in regular expressions.
This commit therefore partially reverts the changes made in 273812f9c5
for closing curly braces (`}`).
Closes gh27467
Previous to this commit, the specificity and quality comparators
(used by MediaType::sortByQualityValue and MediaType::sortBySpecificity)
could result in IllegalArgumentExceptions when used for sorting.
The underlying reason was that the comparators were not transitive, and
both media types with the same type, and types with the same amount of
parameters, would be considered identical by the comparator (result 0).
This commit ensures that the comparators are transitive.
Closes gh-27488
Support code for Apache Tiles and Ehcache has already been removed from
Spring Framework 6.0.
This commit therefore removes the configuration for external links to
these projects.
In order to catch Javadoc errors in the build, we now enable the
`Xwerror` flag for the `javadoc` tool. In addition, we now use
`Xdoclint:syntax` instead of `Xdoclint:none` in order to validate
syntax within our Javadoc.
This commit fixes all resulting Javadoc errors and warnings.
This commit also upgrades to Undertow 2.2.12.Final and fixes the
artifact names for exclusions for the Servlet and annotations APIs.
The incorrect exclusion of the Servlet API resulted in the Servlet API
being on the classpath twice for the javadoc task, which resulted in the
following warnings in previous builds.
javadoc: warning - Multiple sources of package comments found for package "javax.servlet"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.http"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.descriptor"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.annotation"
Closes gh-27480
Prior to this commit, all white space was trimmed from Server Sent Event
data. After this commit, only a leading space is removed (if present).
Closes gh-27473
In order to be able to use text blocks and other new Java language
features, we are upgrading to a recent version of Checkstyle.
The latest version of spring-javaformat-checkstyle (0.0.28) is built
against Checkstyle 8.32 which does not include support for language
features such as text blocks. Support for text blocks was added in
Checkstyle 8.36.
In addition, there is a binary compatibility issue between
spring-javaformat-checkstyle 0.0.28 and Checkstyle 8.42. Thus we cannot
use Checkstyle 8.42 or higher.
In this commit, we therefore upgrade to spring-javaformat-checkstyle
0.0.28 and downgrade to Checkstyle 8.41.
This change is being applied to `5.3.x` as well as `main` in order to
benefit from the enhanced checking provided in more recent versions of
Checkstyle.
Closes gh-27481
As explained in commit a247b83cd9, the
XppDriver from XStream relies on the XPP3 library which publishes
javax.xml.namespace.QName as part of its JAR. The QName type is also
published by the java.xml system module in modular JREs (i.e., Java 9
or higher).
This results in a split package between the unnamed module and the
java.xml system module, which the Java Language Specification defines
as illegal (see §6.5.5.2 and §7.4.3).
Most Java compilers do not currently enforce this rule; however, the
Eclipse compiler does. This makes it impossible to use spring-oxm out
of the box in the Eclipse IDE. In addition, if bug JDK-8215739 is fixed
in future versions of other JDK implementations, this rule will affect
any users using spring-oxm with those JDKs.
This commit therefore switches the default driver in XStreamMarshaller
from XppDriver to DomDriver. Users can naturally switch back to the
XppDriver if they wish, since the driver is configurable.
Closes gh-27464
In 5.3 it became possible to handle exceptions from any handler through
ExceptionHandler's in a ControllerAdvice class, but this is not
mentioned in the docs
See gh-22619, gh-27338
Prior to this commit, the Spring Framework projects could not be
imported into Eclipse IDE when using JDK 17 to build the projects.
The primary obstacle is the fact that Eclipse enforces a strict
"no split packages between the unnamed module and a system module" rule
when building with a "modular JDK" (such as JDK 17).
Resources:
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=536928
- https://bugs.openjdk.java.net/browse/JDK-8215739
- http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-December/014077.html
- https://stackoverflow.com/questions/51094274/eclipse-cant-find-xml-related-classes-after-switching-build-path-to-jdk-10/53824670#53824670
Since the bug (JDK-8215739) has not been fixed in OpenJDK, the strict
"no split packages" rule does not apply to the Java compiler used in
Spring Framework's Gradle build or the compiler in IntelliJ IDEA. Hence,
this issue only arrises when building the framework in Eclipse IDE.
This commit addresses this issue in the following affected projects.
- spring-oxm: removal of the dependency on XPP3 which publishes
javax.xml.namespace.QName as part of the JAR. The QName type is
also published by the java.xml JDK 17 system module. To make the
tests pass, we have switched to using the DomDriver instead of the
XppDriver in our XStream tests.
- spring-test: HtmlUnit has a transitive dependency on xml-apis which
publishes several packages also published by java.xml JDK 17 system
module. Thus, we have explicitly excluded the transitive dependency
on xml-apis for our `optional` configuration.
See gh-27407
Since the team no longer needs the ability to treat Eclipse projects as
WTP modules, this commit removes the obsolete custom WTP configuration
for importing projects into Eclipse IDE.
See gh-27407
This commit partially reverts cf2429b0f0
in order to reinstate -Werror for Groovy compilation in spring-beans.
The `decorating` field in GroovyDynamicElementReader has been changed
from boolean to Boolean in order to avoid the JDK 17 deprecation warning
for use of `new Boolean(false)` which the Groovy compiler apparently
uses behind the scenes when compiling Groovy source code.
In order to allow developers to execute TestNG tests in Eclipse IDE
without installing the TestNG plugin for Eclipse, this commit introduces
a JUnit Platform @Suite class that can be executed within the IDE.
See gh-27407
When not excluded, TestNG will pick up nested TestCase classes and run
them.
This commit therefore filters out `*TestCase` test classes from the
build since these are not intended to be executed with the build.
See gh-27406
Prior to this commit, we had configured separate test tasks for JUnit
and TestNG. In addition, we configured a standard `test` task that
depended on the `junit` and `testNG` tasks, and we had an additional
`aggregateTestReports` task that aggregated the reports from the JUnit
and TestNG test tasks.
Thanks to the introduction of the "TestNG Engine for the JUnit
Platform", this commit simplifies our Gradle build in the spring-test
module by running JUnit 4, JUnit Jupiter, and TestNG tests on the JUnit
Platform in a single Gradle `test` task.
See gh-27406
Prior to this commit, calling `StringUtils#collectionToDelimitedString`
would fail with an NPE if the collection contains null elements.
This commit ensures that null elements are converted as `"null"` in the
resulting String without failure.
See gh-27419
Prior to this commit, the Javadoc task would fail on
`spring-context-indexer` and `spring-instrumentation`. It seems that
missing remote docs or HTTP redirects were failing the process.
This commit removes the missing published Javadocs and updates the
version for the JDK API.
See gh-17778
AspectJ doesn't support JDK17 language level (yet).
For the time being, this commit is downgrading the language level for
the aspectJ generated classes to 1.8.
See gh-27416
Includes hard JDK 9+ API dependency in CGLIB ReflectUtils (Lookup.defineClass) and removal of OutputStream spy proxy usage (avoiding invalid Mockito proxy on JDK 17)
Closes gh-26901
This commit introduces a new `spring-framework-6.0.x` CI pipeline with
JDK 17 baseline.
Note that Kotlin still uses a JDK11 baseline for now, this will be
addressed in gh-27413.
Closes gh-27409
The migration to Gradle 7.2 resulted in a regression for our Eclipse
IDE support: several projects ended up with recursive classpath entries
in their generated .classpath files which prevent those projects from
being built within Eclipse.
This commit addresses this issue with a solution that may well be a
"hack". Nonetheless, a working hack is better than not being able to
import into Eclipse at all.
See gh-26870
This upgrade avoids warnings about the following on Gradle 7.1+.
- The Report.destination property has been deprecated.
- The JavaExec.main property has been deprecated.
See gh-26870
Migrate `CoroutinesUtils` from Kotlin code to Java and drop the
`kotlin-coroutines` module.
This update removes the need for Kotlin tooling IDE plugins to be
installed.
Closes gh-27379
HttpMessageConverterExtractor uses MessageBodyClientHttpResponseWrapper
which may read the first byte of the response stream to check if there
is content. After that it is necessary to use the wrapper to get the
full body.
This commit ensures that when UnknownContentTypeException is raised
it gets the body through the wrapper, or otherwise the first byte is
missed if the InputStream is not markable.
Closes gh-27374
To support the recent changes to our `optional` dependencies plugin,
this commit removes the Eclipse-specific code which no longer appears
to be necessary.
Closes gh-27365
This commit ensures that Servlet 4.0+ is used in the Spring OXM test
suite, as Servlet 4 specific APIs are used in the tests.
This problem was uncovered while fixing gh-27365
This allows the attributes configured on compileClasspath and
runtimeClasspath to independently influence the variant selection when
resolving the optional configuration, allowing it to contribute compile
dependencies (JAVA_API) to the former and runtime dependencies
(JAVA_RUNTIME) to the latter.
Fixes gh-27365
Previously, the optional configuration had no usage attribute. This
resulted in it using the default, JAVA_RUNTIME, which caused it to
only consume the runtime produced by its dependencies and not the
API. Given that the optional configuration is added to the compile
classpath, this was incorrect.
This commit updates the optional configuration to be configured to
consume the Java API of its dependencies. The configuration has
also been marked as not being for consumption. This prevents other
projects attempting to consume the optional variant of a project
that has the optional dependencies plugin applied and further
aligns it with Gradle's built-in configurations of a similar nature.
See gh-27365
This commit updates the defaultResponseCharacterEncoding() `default`
method in ConfigurableMockMvcBuilder so that it throws an
UnsupportedOperationException instead of silently ignoring the user's
request to set the default response character encoding.
Note, however, that AbstractMockMvcBuilder already overrides the
default method with a concrete implementation which is used by default
in MockMvc.
See gh-27230
This commit applies several optimizations to StringUtils#cleanPath and
related methods:
* pre-size pathElements deque in StringUtils#cleanPath with
pathElements.length elements, since this this is the maximum size and
the most likely case.
* optimize StringUtils#collectionToDelimitedString to calculate the size
of the resulting String and avoid array auto-resizing in the
StringBuilder.
* If the path did not contain any components that required cleaning,
return the (normalized) path as-is. No need to concatenate the prefix
and the trailing path.
See gh-26316
This commit also fixes a bug introduced in commit e99b43b91e, where
java.time.Duration strings were converted to milliseconds and then
converted again using the configured TimeUnit.
See gh-27309
This commit introduces a new `timeUnit` attribute in the @Scheduled
annotation to allow the user to specify a time unit other than
milliseconds.
Closes gh-27309
It happens very often that WebTestClient is used in heavyweight
integration tests, and it's a hindrance to developer productivity to
fix one failed assertion after another. Soft assertions help a lot by
checking all conditions at once even if one of them fails.
This commit introduces a new expectAllSoftly(..) method in
WebTestClient to address this issue.
client.get().uri("/hello")
.exchange()
.expectAllSoftly(
spec -> spec.expectStatus().isOk(),
spec -> spec.expectBody(String.class).isEqualTo("Hello, World")
);
Closes gh-26969
It happens very often that MockMvc is used in heavyweight integration
tests. It's no use to waste time to check if another condition has been
fixed or not. Soft assertions help a lot by checking all conditions at
once even if one of them fails.
See gh-26917
Co-authored-by: Sach Nguyen <sachnbbkhn@gmail.com>
Prior to this commit, if the user tested file upload support with
HtmlUnit and MockMvc by invoking HtmlFileInput.setData() instead of
HtmlFileInput.setFiles(), the in-memory file data was simply ignored.
This commit addresses this issue by creating a MockPart from the
in-memory data in HtmlUnitRequestBuilder.
Closes gh-27199
Prior to this commit, the hasContributors() method incorrectly returned
false if contributors had been configured.
This commit fixes the logic in hasContributors() and documents it.
Closes#27271
To improve the developer experience and avoid the use of String
literals, this commit provides overloaded support via Charset for
character encoding in MockHttpServletRequestBuilder and
ContentResultMatchers.
Closes gh-27231
Commit e4b9b1fadb introduced support for setting the default character
encoding in MockHttpServletResponse.
This commit introduces support for configuring the default character
encoding in the underlying MockHttpServletResponse used in MockMvc.
Closes gh-27230
Prior to this commit, MockMvc applied global ResultMatchers before
global ResultHandlers. This lead to unexpected scenarios where a
failing matcher would prevent a handler from being applied.
One concrete use case is `alwaysDo(print(System.err))` which should
print out MockMvc results for debugging purposes. However, if MockMvc is
configured with something like `alwaysExpect(content().string("?"))`
and the expectation fails, the user will never see the expected debug
output to help diagnose the problem.
This commit addresses this issue by applying global ResultHandlers
before ResultMatchers in MockMvc.
Closes gh-27225
Prior to this commit, it was possible to set the character encoding
in MockHttpServletResponse via setCharacterEncoding() or
setContentType(); however, those methods append "charset=..." to the
Content-Type header which may not be an acceptable side effect.
This commit addresses this shortcoming by introducing a new
setDefaultCharacterEncoding() in MockHttpServletResponse which allows
one to override the previously hard coded value of "ISO-8859-1". In
addition, setDefaultCharacterEncoding() does not modify the Content-Type
header.
The reset() method has also been updated to reset the character encoding
to the configured default character encoding.
Closes gh-27214
This commit improves the documentation for @Cacheable to point out that
`null` will be stored in the cache for an empty `Optional` return value.
Closes gh-27184
Prior to this commit, if the TaskExecutor configured in
WebSocketMessageBrokerStats for the inboundChannelExecutor or
outboundChannelExecutor was not a ThreadPoolTaskExecutor, a
StringIndexOutOfBoundsException was thrown when attempting to parse the
results of invoking toString() on the executor.
The reason is that ThreadPoolTaskExecutor delegates to a
ThreadPoolExecutor whose toString() implementation generates text
containing "pool size = ...", and WebSocketMessageBrokerStats'
getExecutorStatsInfo() method relied on the presence of "pool" in the
text returned from toString().
This commit fixes this bug by ensuring that the text returned from
toString() contains "pool" before parsing the text. If "pool" is not
present in the text, getExecutorStatsInfo() now returns "unknown"
instead of throwing a StringIndexOutOfBoundsException.
Closes gh-27209
A side effect of 71995a9087 caused the
dynamic table of contents in the left-hand side navigation to no longer
be displayed, likely due to the missing "details" DIV.
This commit addresses this issue by applying the custom header only to
index.adoc.
Consequently, the TOC is now displayed again on all pages except the
index page, but the customized header is no longer applied to those
pages.
We may revisit this issue if we decide that we want the custom header
on all pages (and not just the index page).
Closes gh-27177
If the ThreadPoolTaskExecutor is dynamically changed with an invalid value
the state of the ThreadPoolTaskExecutor does no longer correctly represent
the state of the underlying ThreadPoolExecutor
This commit makes JettyServerHttpRequest aware of
HttpServletRequestWrapper, and JettyServerHttpResponse aware of
HttpServletResponseWrapper.
Closes gh-27146
Before this commit, JettyClientHttpResponse checked for the presence of
a server-side class to determine whether it is running on Jetty 10.
Unfortunately, that class is not necessarily present when just using the
Jetty client.
This commit improves the Jetty 10 check, so that it also works when
the Jetty client is used without the server.
Closes gh-27136
This commit makes sure that we no longer use the internal API in the
Jetty support for the WebClient. With this change, we are able to
support both Jetty 9, 10, and 11.
Closes gh-27112
This reverts commit d6df4a6577 because running
gradle generatePomFileForMavenJavaPublication throws a
kotlin.KotlinNullPointerException error with Kotlin 1.5.20.
Revert Mockito upgrade done in 5d919dc094 because
Byte Buddy transitive upgrade from 1.11.1 to 1.11.3 seems to break Mockk tests
with java.security.AccessControlException related errors, so probably
better to wait Mockito using Byte buddy 1.11.5+ which seems to refine
this area, see https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.11.5.
To slightly improve performance, this commit switches to
StringBuilder.append(char) instead of StringBuilder.append(String)
whenever we append a single character to a StringBuilder.
Closes gh-27098
Prior to this commit, ConfigurationClass implemented equals(),
hashCode(), and toString(), but BeanMethod did not.
This commit introduces equals(), hashCode(), and toString()
implementations in BeanMethod for consistency with ConfigurationClass
to make it possible to use BeanMethod instances to index additional
metadata as well.
In order to properly implement equals() in BeanMethod, the method
argument types are required, but these are not directly available in
BeanMethod. However, they are available via ASM when processing @Bean
methods. This commit therefore implements equals(), hashCode(), and
toString() in SimpleMethodMetadata which BeanMethod delegates to.
For completeness, this commit also implements equals(), hashCode(), and
toString() in StandardClassMetadata, StandardMethodMetadata, and
SimpleAnnotationMetadata.
Closes gh-27076
Prior to this commit, the toString() implementation did not separate
method argument types with a comma or any form of separator, leading
to results such as:
org.example.MyClass.myMethod(java.lang.Stringjava.lang.Integer)
instead of:
org.example.MyClass.myMethod(java.lang.String,java.lang.Integer)
Closes gh-27095
This commit defines the doc-root and api-spring-framework attributes
once in docs.gradle instead of duplicating them in each *.adoc file.
This commit also introduces a new docs-spring-framework global
attribute.
This commit disables the automatic header generation from Asciidoc's
default template and replaces it with a custom header that omits the
"Version" label before the revision number. The revision number is also
displayed in a simple span tag in order to reduce the amount of
vertical space taken by the header.
Prior to this commit, if a PathContainer was created using
Options.MESSAGE_ROUTE, DefaultPathSegment#parameters() returned a
mutable map which would allow the user to modify the contents of the
static, shared EMPTY_PARAMS map in DefaultPathContainer.
This commit prevents corruption of the shared EMPTY_PARAMS map by
ensuring that parameters stored in DefaultPathSegment are always
immutable.
Closes gh-27064
This commit revisits the recently updated `PORT_PATTERN` in
`UriComponentsBuilder`. The fix introduced in gh-26905 fails with
ambiguous URL patterns, especially when the port and path parts of the
pattern are hard to differentiate, for example
"https://localhost:{port}{path}".
This commit reinstates the previous behavior without undoing the actual
fix. The only limitation introduced here is the fact that only a single
pattern variable is allowed for the port pattern part.
Fixes gh-27039
Prior to this commit, the `HttpComponentsClientHttpConnector`
implementation could accept or create a default `HttpClient` instance
but not expose it as part of its API. This effectively prevents
applications from properly closing the associated resources when
disposing of the connector.
This commit implements the `Closeable` interface on the connector to
allow this use case.
Closes gh-27032
Proposed change aimed to keep coherence between variable declaration
and static initialization code, which stores 9 values, not 8, in these
two maps.
Closes gh-27016
Prior to this commit, in some cases application context startup steps
could be created concurrently, which could cause issues with the current
implementation tracking the parent/child relationship between steps.
This commit ensures that the flight recorder implementation is using
thread safe collection implementations for that.
Fixes gh-26941
Make sure that we use the parameter name in MultipartBodyBuilder::part
when adding a Part, instead of using the name specified in the
'Content-Disposition' header that might have been in the part's headers.
Closes gh-27007
This commit improves the Javadoc regarding transactional semantics for
@TransactionalEventListener methods invoked in the AFTER_COMMIT,
AFTER_ROLLBACK, or AFTER_COMPLETION phase. Specifically, the
documentation now points out that interactions with the underlying
transactional resource will not be committed in those phases.
Closes gh-26974
Prior to this commit, the `RouterFunctionMapping` WebFlux.fn variant
would set the `HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE` as an
exchange attribute. This is useful for instrumentation purposes.
The WebMvc.fn variant would not do the same; this would lead to
"UNKNOWN" path metrics tags.
This commit ensures that the `RouterFunctionMapping` WebMvc.fn variant
does set the `BEST_MATCHING_PATTERN_ATTRIBUTE` and
`BEST_MATCHING_HANDLER_ATTRIBUTE` request attributes.
Closes gh-26963
Many of the utility methods in ScriptUtils are public only because they
were once invoked from JdbdTestUtils in spring-test, which is no longer
the case. Consequently, there should no longer be a need for any
external clients to invoke such methods.
To address this, this commit formally deprecates the following methods
in ScriptUtils in spring-jdbc.
- readScript(...)
- containsSqlScriptDelimiters(...)
- splitSqlScript(...)
Closes gh-26947
Prior to this commit, many of the utility methods in ScriptUtils in
spring-r2dbc were public by accident: they were copied from ScriptUtils
in spring-jdbc without changing the visibility when spring-r2dbc was
introduced in Spring Framework. 5.3 GA.
This commit corrects this mistake by removing internal APIs from
ScriptUtils in spring-r2dbc from the public contract.
See gh-26947
This commit picks up where 569ce840cf left off, by correctly invoking
the new containsStatementSeparator(...) method from
executeSqlScript(...) in ScriptUtils in spring-r2dbc.
See gh-26911
Prior to this commit, the implementations of
ScriptUtils.containsSqlScriptDelimiters() in spring-jdbc and
spring-r2dbc did not ignore comments when searching for the statement
delimiter within an SQL script. This resulted in subtle bugs if a
comment contained a single single-quote or single double-quote, since
the absence of the closing single-quote or double-quote led the
algorithm to believe that it was still "within a text literal". Similar
issues could arise if a comment contained the sought statement
delimiter but the rest of the script did not contain the sought
statement delimiter. In such cases, the algorithms in ScriptUtils could
erroneously choose an incorrect statement delimiter -- for example,
using the fallback statement delimiter instead of the delimiter
specified by the user.
This commit avoids such bugs by ignoring single-line comments and block
comments when searching for the statement delimiter within an SQL
script.
Closes gh-26911
Prior to this commit, the containsSqlScriptDelimiters() method in
ScriptUtils ignored delimiters enclosed in single quotes but not those
enclosed within double quotes, which contradicts the algorithm in
splitSqlScript() and therefore constitutes a bug.
This commit fixes this bug in the ScriptUtils implementations in
spring-jdbc and spring-r2dbc.
Closes gh-26935
This commit makes sure that the DefaultPartHttpMessageReader uses a
random temporary directory to store uploaded files, so that two
instances do not collide.
See gh-26931
This commit makes sure that Synchronoss uses a random temporary
directory to store uploaded files, so that two instances do not collide.
Closes gh-26931
Recent commit dddcc5e9ad ensured a
trailing "/" in the Origin header has no effect. This commit does the
same for a trailing "/" in configured patterns.
See gh-26892
The pattern was changed in 65797d04f2
to check for characters up until "/", instead of for digits, but now
also checks up until "?" and "#".
Closes gh-26905
Prior to this commit, when Web MVC attempted to resolve a constructor
argument for a data class constructor with @ModelAttribute binding,
ModelAttributeMethodProcessor failed to unwrap the array returned by
WebRequest.getParameter(String).
According to the Javadoc for WebRequest.getParameter(String), "a
single-value parameter will be exposed as an array with a single
element."
This commit fixes this issue by extracting the single value from such
an array and using that as the constructor argument (potentially
converted by the WebDataBinder).
Closes gh-25200
This commit revises the fix submitted in 959e6d1745 by ensuring that
empty file input is converted to a MockPart with the supplied name, an
empty filename, "application/octet-stream" as the content type, and
empty content.
This aligns with the behavior of Servlet containers, as tested with the
interaction between Firefox and a standard Servlet running in a Jetty
Servlet container.
Closes gh-26799
Prior to this commit, when using HtmlUnit with empty file input,
MockMvc's HtmlUnitRequestBuilder would throw a NullPointerException
when attempting to create a MockPart based on the null File.
This commit ensures that empty file input is converted to a MockPart
with a valid name but with a null filename, a null content type, and
empty content.
Closes gh-26799
Prior to this commit, we registered custom values in the build scan for
the main and test toolchains based on input values provided via the
mainToolchain and testToolchain project properties.
Beginning with this commit, the custom values we register are based on
the available metadata for the resolved JDK/JVM for each toolchain.
For example, instead of registering the following custom value...
Test toolchain : JDK11
... we now register the following which includes the vendor, version,
and installation path of the JDK/JVM.
Test toolchain : AdoptOpenJDK 11 (/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home)
Once Gradle's JavaInstallationMetadata includes the exact version, we
will likely use that instead of the installation path.
See gh-25787
Prior to this commit, the task parameters for the CI project checks were
overridden by a task anchor. This commit splits the anchor declaration
and ensures that the `TEST_TOOLCHAIN` setting is set for the JDK
variant builds.
See gh-25787
Commit 3eec27a723 introduced a custom resource filter for projects
imported into Eclipse IDE. However, commit 85eb589c2e introduced
generated source files within the Gradle 'build' folder, and the filter
prevents Eclipse from seeing the generated sources, resulting in build
errors within the spring-oxm project in Eclipse.
This commit therefore effectively reverts 3eec27a723 by removing the
resource filter.
See gh-25787
Prior to this commit, @ModelAttribute(binding=false) was honored with
Spring Web MVC but not with WebFlux.
This commit adds support for disabling binding via @ModelAttribute with
WebFlux by adding a check to resolveArgument(...) in
ModelAttributeMethodArgumentResolver.
Closes gh-26856
This commit fixes various issues with the configuration of the Gradle
Java toolchain in the build.
First, the configuration of build properties is fixed in the CI pipeline
because it wasn't properly checked.
The JMH plugin is also upgraded and we now configure its toolchain
support.
This commit also rewrites the XJC tasks in the spring-oxm module,
leveraging a Gradle plugin that creates actual compile tasks we can
configure.
See gh-25787
This commit makes sure that LinkedCaseInsensitiveMap::computeIfAbsent
honors the contract of the method, and also replaces the old entry if
that mapped to null.
Closes gh-26868
This commit makes sure that LinkedCaseInsensitiveMap::putIfAbsent honors
the contract of the method, and also replaces the old entry if that
mapped to null.
Closes gh-26868
This commit fixes a potential memory leak, since PropertyComparator
previously kept an indirect reference to the value it last compared.
Closes gh-26869
This commit makes sure that any error handlers registered on the route
are also applied when an error occurs asynchronously. This commit
applies to asynchronous bodies with both CompletableFuture and Reactive
Streams, as well as completely asynchronous responses.
Closes gh-26831
Prior to this commit, MySQLMaxValueIncrementer could not be used when
the MySQL database was configured to use safe-updates mode.
See https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates
This commit introduces a `limit 1` clause to the generated update
statement to allow MySQLMaxValueIncrementer to be compatible with
MySQL safe-updates mode.
Closes gh-26858
Before this commit, HttpStatus::resolve used the values() method in its
logic. This causes a new array to be allocated for each invocation,
and results in memory overhead.
This commit makes a copy of the HttpStatus values array, and uses that
to resolve status codes.
Closes gh-26842
Prior to this commit, evaluating validation hints for
@javax.validation.Valid caused exceptions being raised when getting the
value of this annotation, which does not exist. Bypassing
AnnotationUtils.getValue() in those cases can improve performance by
avoiding the cost incurred by raising exceptions.
See gh-26787
Prior to this commit, two tests for exception handling regarding
@DateTimeFormat processing only passed on Java 8. This is due to the
fact that the toString() implementation for annotations changed in Java
9. Specifically, the representation for arrays changed from [] to {},
and strings are enclosed in double quotes beginning with Java 9.
This commit ensures that the affected @DateTimeFormat tests pass on
Java 9+, by making the assertions more lenient regarding toString()
output for annotations.
See gh-26777
See gh-26804
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.
gh-26777 addressed that regression for `java.time` support; whereas,
this commit addresses that regression for legacy Date types.
This commit ensures that the original ParseException is set as the
cause for any newly created ParseException, thereby retaining the
original exception as the root cause.
Closes gh-26804
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.
This commit ensures that the original DateTimeParseException is set as
the cause for any newly created DateTimeParseException, thereby
retaining the original exception as the root cause.
Closes gh-26777
Some operating systems delete temp files not just when booting up, but
also during operation. This commit makes sure that the
DefaultPartHttpMessageReader recreates the directory used to store
files in, if it's not there.
Closes gh-26790
This commit allows the spring-expression module to be more easily repackaged
for embedding in third-party JARs -- for example, via the Shadow Gradle plugin.
Closes gh-26779
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header, which is sent when the client sends unsupported
data in PATCH requests.
See section 2.2 of RFC 5789.
Closes gh-26759
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header in OPTIONS requests, as defined in section 3.1 of
RFC 5789.
See gh-26759
This commit adds support for Kotlin non-nullable type which resolves
to primitive Java types in BridgeMethodResolver#findBridgedMethod.
Closes gh-26585
Prior to this commit, if a test class annotated with @DirtiesContext
and @EnabledIf/@DisabledIf with `loadContext = true` was disabled due
to the evaluated SpEL expression, the ApplicationContext would not be
marked as dirty and closed.
The reason is that @EnabledIf/@DisabledIf are implemented via JUnit
Jupiter's ExecutionCondition extension API which results in the entire
test class (as well as any associated extension callbacks) being
skipped if the condition evaluates to `disabled`. This effectively
prevents any of Spring's TestExecutionListener APIs from being invoked.
Consequently, the DirtiesContextTestExecutionListener does not get a
chance to honor the class-level @DirtiesContext declaration.
This commit fixes this by implementing part of the logic of
DirtiesContextTestExecutionListener in
AbstractExpressionEvaluatingCondition (i.e., the base class for
@EnabledIf/@DisabledIf support). Specifically, if the test class for an
eagerly loaded ApplicationContext is disabled,
AbstractExpressionEvaluatingCondition will now mark the test
ApplicationContext as dirty if the test class is annotated with
@DirtiesContext.
Closes gh-26694
This commit fixes the missing pieces in our Maven Central publication
pipeline. Our first attempt at releasing with it showed a few problems:
* the promote task did not have the artifacts downladed with the
artifactory repository
* we applied the wrong Sonatype credentials to the task
* the github changelog task would fail because of docker rate limiting
since we were not using the right type of resource, which is
configured with the proper caching mechanism
See gh-26654
Prior to this commit, the Spring Framework build would rely on
setting a custom Java HOME for building all sources and tests
with that JDK.
This approach is not flexible enough, since we would be testing
the source compatibility against a recent JDK, but not a common
case experienced by the community: compiling and running
application code with a recent JDK and the official, JDK8-based
Framework artifacts.
This method is also limiting our choice of JDKs to the ones
currently supported by Gradle itself.
This commit introduces the support of Gradle JVM Toolchains in
the Spring Framework build.
We can now select a specific JDK for compiling the main
SourceSets (Java, Groovy and Kotlin) and another one for
compiling and running the test SourceSets:
`./gradlew check -PmainToolChain=8 -PtestToolchain=15`
Gradle will automatically find the JDKs present on the host or
download one automcatically. You can find out about the ones
installed on your host using:
`./gradlew -q javaToolchains`
Finally, this commit also refactors the CI infrastructure to:
* only have a single CI image (with all the supported JDKs)
* use this new feature to compile with JDK8 but test it
against JDK11 and JDK15.
Closes gh-25787
We now support Oracle's bind marker scheme that identifies dynamic
parameters using names that are prefixed with a colon such as
`:P0_myparam`.
Closes gh-26680
Prior to this commit, @DateTimeFormat only supported a single format
for parsing date time values via the style, iso, and pattern attributes.
This commit introduces a new fallbackPatterns attribute that can be
used to configure multiple fallback patterns for parsing date time
values. This allows applications to accept multiple input formats for
date time values.
For example, if you wish to use the ISO date format for parsing and
printing but allow for lenient parsing of user input for various
additional date formats, you could annotate a field or method parameter
with configuration similar to the following.
@DateTimeFormat(
iso = ISO.DATE,
fallbackPatterns = { "M/d/yy", "dd.MM.yyyy" }
)
Closes gh-20292
This commit skips the Bintray-related tasks in our CI pipeline and
instead relies on Maven Central for publishing Spring Framework
artifacts.
This commit also updates the CI pipeline to sign the artifacts directly
with the `artifactory-resource`.
Closes gh-26654
Previously we registered 3 AsyncListener's from the request, from the
response, and from the Servlet adapter.
After this change, only the Servlet adapter registers a listener and
the others are delegated to. This consolidates the handling of
AsyncListener events so that it's easier to discover, trace, and
enforce the order of handling.
See gh-26434
Prior to this commit, a method-level @CrossOrigin maxAge value did not
override a class-level @CrossOrigin maxAge value. This contradicts the
Javadoc for @CrossOrgin which states the following.
For those attributes where only a single value can be accepted such
as allowCredentials and maxAge, the local overrides the global
value.
This commit ensures that a method-level @CrossOrigin maxAge value
overrides a class-level @CrossOrigin maxAge value.
Closes gh-26619
Prior to this commit, `ServerHttpRequest.mutate()` would not reflect
changes made on the "Accept" and "Content-Type" HTTP headers.
This was due to the fact that the instantiation of a new request based
on the mutated values would not use the writable HTTP headers used
during the mutation, but rather a read-only view of the headers backed
by `ReadOnlyHttpHeaders`.
`ReadOnlyHttpHeaders` caches those values for performance reasons, so
getting those from the new request would not reflect the changes made
during the mutation phase.
This commit ensures that the new request uses the mutated headers.
Fixes gh-26615
This commit ensures handling is cancelled in case of onError/Timeout
callback from the Servlet container.
Separately we detect the same in ServletServerHttpRequest and
ServletServerHttpResponse, which signal onError to the read publisher
and cancel writing, but if the onError/Timeout arrives after reading
is done and before writing has started (e.g. longer handling), then
neither will reach handling.
See gh-26434, gh-26407
For setAsText, if the text argument is a file: URL for a path that does not exist, Paths.get(text) is called where text is a file: URL, which doesn't work - the result is an InvalidPathException.
To fix this issue, also check that the resource isn't a file before calling Paths.get(). That way, resources that are files skip to the other branch.
Class.getResource, ClassLoader.getResource, and ClassLoader.getSystemResource will throw IllegalArgumentException if a malformed URL is provided to them.
According to its javadoc, resolveURL should return null if not resolvable, so catch the IllegalArgumentException and return null.
Prior to this commit, the implementation of processKeyedProperty() in
AbstractNestablePropertyAccessor resulted in a
`java.lang.IllegalArgumentException: array element type mismatch` when
the property expression had more than one property key and the last key
should cause the array to grow automatically.
For example, given a property `int[][] multiArray` and property
expression `multiArray[1][3]`, the `processKeyedProperty()` method
created a new array object and assigned it to `multiArray`; whereas,
the new array object should have be assigned to `multiArray[1]`.
This commit fixes this issue.
Closes gh-26600
In order to reduce the focus on the deprecated @Required support, this
commit removes the RequiredAnnotationBeanPostProcessor section and
replaces it with a TIP and an updated NOTE.
See gh-26578
Since Spring Framework 5.2, the LoadTimeWeaver no longer weaves bean
classes annotated with @Component. This is a regression caused by the
changes in 40c62139ae, stemming from the fact that any class annotated
or meta-annotated with @Component is considered to be a candidate
configuration class in 'configuration lite' mode (i.e., a class without
the @Configuration annotation and without any @Bean methods) and
therefore now has its class eagerly loaded. This results in the class
being loaded before the LoadTimeWeaver has a chance to weave it.
This commit fixes this regression by explicitly avoiding eager class
loading for any 'lite' @Configuration or @Component class without @Bean
methods.
Closes gh-26199
Prior to this commit, `ResourceUrlProvider` would listen and consider
all `ContextRefreshedEvent` and use the given context to detect
`SimpleUrlHandlerMapping`.
This could lead to situations where a `ResourceUrlProvider` uses another
application context than its own (in a parent/child context setup) and
detect the wrong set of handlers.
Because `ResourceUrlProvider` locks itself once the auto-detection is
done, we need to ensure that it considers only events sent by its
application context.
Fixes gh-26561
Prior to this commit, MockHttpServletResponse only included the Expires
attribute in the generated Cookie header if the Max-Age attribute had
also been set.
This commit supports including the Expires attribute in the generated
Cookie Header even when the Max-Age attribute has not been set.
Closes gh-26558
Add factory methods to `AbstractEnvironment` that allow a custom
`ConfigurablePropertyResolver` and `MutablePropertySources` instance
to be used.
See gh-26462
With the introduction of the -H:+InlineBeforeAnalysis native image
compiler flag in GraalVM 21.0.0, it is now possible to use an utility method and get code
removal at build time.
This flag will be enabled as of Spring Native 0.9.0.
closes gh-25795
This commit updates the reference manual to point out that one may use
`.` instead of `$` as the nested class separator when providing a fully
qualified class name for a nested class in XML configuration.
This commit also updates the test for ClassUtils#forName to assert
support for `.` instead of `$`.
Closes gh-26540
gh-24281 introduced support to honor generic type information in
BeanUtils.copyProperties(), but that introduced a regression.
Specifically, if the supplied source or target object lacked generic
type information for the return type of the read-method or the
parameter type of the write-method for a given property, respectively,
the two properties would be considered a mismatch and ignored. This can
occur if the source or target object is a java.lang.reflect.Proxy since
the dynamically generated class for the proxy loses the generic type
information from interfaces that the proxy implements.
This commit fixes this regression by ignoring generic type information
if either the source or target property is lacking generic type
information.
Closes gh-26531
This commit better aligns how URI variable placeholders are detected
in UriComponentsBuilder#encode (i.e. the pre-encoding of the literal
parts of a URI template) and how they are expanded later on.
The latter relies on a pattern that stops at the first closing '}'
which excludes the possibility for well-formed, nested placeholders
other than variables with regex syntax, e.g. "{year:\d{1,4}}".
UriComponentsBuilder#encode now also stops at the first closing '}' and
further ensures the placeholder is not empty and that it has '{' before
deciding to treat it as a URI variable.
Closes gh-26466
This commit changes the condition in the if-block to check the number of
available processors instead of currently active threads with the hope
that doing so will prove more reliable on the CI server.
`spring-beans` ships a `YamlProcessor` that's used as a base class by
`YamlMapFactoryBean` and `YamlPropertiesFactoryBean`. These
implementations have a clear use case: mapping application-internal Yaml
documents for configuration or infrastructure purposes.
Since this use case rarely requires extended types support from the
underlying library, and since we're offering ways to list custom types
(since #25152), we'll restrict to java standard types only by default.
This simplifies the setup and focuses the abstract class on the core
use cases.
Closes gh-26530
This commit makes sure the StringDecoder supports stripping off
multi-line delimiters, such as \r\n. Specifically, we ensure that the
delimiter is stripped from the joined buffer.
Closes gh-26511
When a broker message handler is not configured with any prefixes, it will
process all messages by default, but user destination messages should be
pre-processed by the userDestinationMessageHandler first. This change
protects against that.
Closes gh-26474
This commit aligns the documentation in the reference manual with the
actual source code for StoredProcedure with regard to public execute()
methods.
Closes gh-26505
Previously this method returned headers only when a Content-Type part header
was present. Now it is guaranteed to return headers (possibly empty) as long
as there is a MultipartFile or Part with the given name.
Closes gh-26501
Prior to this commit, if an SQLException was thrown while retrieving
column metadata from the database, SimpleJdbcInsert would generate an
INSERT statement that was syntactically valid but missing columns,
which could lead to data silently missing in the database (for nullable
columns).
This commit fixes this by clearing all collected column metadata if an
SQLException is thrown while processing the metadata. The result is
that an InvalidDataAccessApiUsageException will be thrown later while
generating the INSERT statement. The exception message now contains an
additional hint to make use of SimpleJdbcInsert#usingColumns() in order
to ensure that all required columns are included in the generated
INSERT statement.
SimpleJdbcCall can also encounter an SQLException while retrieving
column metadata for a stored procedure/function, but an exception is
not thrown since a later invocation of the stored procedure/function
will likely fail anyway due to missing arguments. Consequently, this
commit only improves the warning level log message by including a hint
to make use of SimpleJdbcCall#addDeclaredParameter().
Closes gh-26486
Prior to this commit, calls to setLocale() MockHttpServletResponse
would result in a NullPointerException if the supplied Locale was null.
Although the Javadoc for setLocale(Locale) and addHeader(String, String)
in javax.servlet.ServletResponse does not specify how a null
Locale should be handled, both Tomcat and Jetty simply ignore a null
value.
This commit therefore updates MockHttpServletResponse to silently
ignore a null Locale passed to setLocale().
Closes gh-26493
Prior to this commit, calls to setHeader() and addHeader() in
MockHttpServletResponse would result in an IllegalArgumentException or
NullPointerException if the supplied header value was null.
Although the Javadoc for setHeader(String, String) and
addHeader(String, String) in javax.servlet.http.HttpServletResponse
does not specify how a null header value should be handled, both Tomcat
and Jetty simply ignore a null value. Furthermore,
org.springframework.http.HttpHeaders.add(String, String) declares the
headerValue parameter as @Nullable.
This commit therefore updates MockHttpServletResponse to silently
ignore null header values passed to setHeader() and addHeader().
Closes gh-26488
1. Update the HandlerMapping contract to state that CORS checks are expected
to be applied before returning a handler.
2. DispatcherHandler checks explicitly for pre-flight requests or CORS failed
requests and skips handling for both. Technically no change since
AbstractHandlerMapping already returns a NO_OP_HANDLER for those cases.
The purpose however is for the DispatcherHandler to also guarantee more
explicitly that no such handling can take place for such cases.
As one consequence, this makes it possible to invoke the DispatcherHandler from
anywhere in the WebFilter chain in order to "handle" a pre-flight request, and
then skip the rest of the WebFilter chain.
See gh-26257
Prior to this commit, if the DataSource in the
DataSourceFromTransactionManager was wrapped in a proxy implementing
InfrastructureProxy, SqlScriptsTestExecutionListener would throw an
exception stating that the DataSource in the ApplicationContext and the
DataSource in the DataSourceFromTransactionManager were not the same.
This commit unwraps both data sources and compares the underlying
target instances to check for equality.
In addition, this commit makes the unwrapResourceIfNecessary() method in
TransactionSynchronizationUtils public.
Closes gh-26422
This commit introduces warnings in invokeBeanFactoryPostProcessors()
and registerBeanPostProcessors() to deter people from submitting PRs
that result in breaking changes.
Closes gh-26401
Prior to this commit, `SimpleUrlHandlerMapping` and other
implementations of `AbstractUrlHandlerMapping` would not strip the
Servlet context path from the request path before performing path
matching with PathPattern instances.
This resulted in requests not matching as expected if the application
was configured with a Servlet context path.
This commit ensures that the `RequestPath` "path whithin the
application" is used for matching against path patterns.
Fixes gh-26411
This commit makes sure that the CronExpression rolls back the time to
midnight when dealing with Quartz expression fields (such as "L", "LW",
etc.).
Closes gh-26390
Remove support for open polymorphic serialization in
kotlinx.serialization web converters and codecs in order
to prevent serialization handling suitable for Jackson
or other general purpose Java JSON libraries.
This will probably need further refinements for collections
for example, and could ultimately be fixed when
kotlinx.serialization will provide a dedicated function to
evaluate upfront if a type can be serialized or not.
Closes gh-26298
This commit documents ApplicationContext initialization and shutdown
logging semantics for console output triggered in conjunction with the
Spring TestContext Framework.
Closes gh-25385
Prior to this commit, WebFlux native headers adapters would delegate the
`httpHeaders.keySet` to underlying implementations that do not honor the
`remove*` methods.
This commit fixes the `Set` implementation backing the
`httpHeaders.keySet` and ensures that headers can be safely removed from
the set.
Fixes gh-26361
Instead of using a new bounded elastic scheduler per
DefaultPartHttpMessageReader instance, which creates daemon threads that
are not shut down, we now use the shared bounded elastic scheduler.
Closes gh-26347
This commit only writes the 'charset' parameter in the written headers
if it is non-default (not UTF-8), since RFC7578 states that the only
allowed parameter is 'boundary'.
See gh-25885
Closes gh-26290
An empty buffer for RSocket is an empty message and while some codecs
such as StringDecoder may be able turn that into something such as an
empty String, for other formats such as JSON it is invalid input.
Closes gh-26344
Prior to this commit, the `ServletServerHttpResponse` would copy headers
from the `HttpHeaders` map and calls methods related to headers exposed
as properties (content-type, character encoding).
Unlike its reactive variant, this would not set the content length.
Depending on the Servlet container implementation, this could cause
duplicate Content-Length response headers in the actual HTTP response.
This commit aligns both implementations and ensures that the
`setContentLengthLong` method is called if necessary so that the Servlet
container can ensure a single header for that.
Fixes gh-26330
Prior to this commit, the `ResourceHttpRequestHandler` would write the
resource size to the "Content-Length" response header.
This is already done by the underlying `ResourceHttpMessageConverter`
and `ResourceRegionHttpMessageConverter`.
This commit avoid this duplicate operation and delegates instead to the
converters.
See gh-26330
Closes gh-26340
- Remove unused clone() code left-over from previous way of cloning.
- Lazy instantiation of ServerCodecConfigurer in
HttpWebHandlerAdapter since in most cases the configurer instance
is set externally.
Closes gh-26263
This commit reverts some changes done in 2d5f9723fa
in order to fix JdbcOperations.queryForObject and
JdbcOperations.queryForList.
It is not possible to provide a vararg variant in Kotlin
for now due to a signature clash, but that will probably
make sense in Spring Framework 6 timeframe along to array
based variant removal for both Java and Kotlin.
Closes gh-26312
Since support for the commandName attribute was removed from the
implementation of FormTag in Spring Framework 5.0, the presence of the
commandName attribute in the spring-form.tld file is no longer valid
and can lead one to assume that the commandName attribute is still
supported -- for example when using code completion in a JSP editor.
This commit therefore removes the obsolete commandName attribute in
spring-form.tld.
Closes gh-26337
This commit introduces tests that verify support for using
@PropertySource as a repeatable annotation without the
@PropertySources container, both locally on an @Configuration class
and on a custom composed annotation.
See gh-26329
This commit introduces a new feature in the Spring TestContext
Framework (TCF) that provides support for recording application events
published in the ApplicationContext so that assertions can be performed
against those events within tests. All events published during the
execution of a single test are made available via the ApplicationEvents
API which allows one to process the events as a java.util.Stream.
The following example demonstrates usage of this new feature.
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
class OrderServiceTests {
@Autowired
OrderService orderService;
@Autowired
ApplicationEvents events;
@Test
void submitOrder() {
// Invoke method in OrderService that publishes an event
orderService.submitOrder(new Order(/* ... */));
// Verify that an OrderSubmitted event was published
int numEvents = events.stream(OrderSubmitted.class).count();
assertThat(numEvents).isEqualTo(1);
}
}
To enable the feature, a test class must be annotated or meta-annotated
with @RecordApplicationEvents. Behind the scenes, a new
ApplicationEventsTestExecutionListener manages the registration of
ApplicationEvents for the current thread at various points within the
test execution lifecycle and makes the current instance of
ApplicationEvents available to tests via an @Autowired field in the
test class. The latter is made possible by a custom ObjectFactory that
is registered as a "resolvable dependency". Thanks to the magic of
ObjectFactoryDelegatingInvocationHandler in the spring-beans module,
the ApplicationEvents instance injected into test classes is
effectively a scoped-proxy that always accesses the ApplicationEvents
managed for the current test.
The current ApplicationEvents instance is stored in a ThreadLocal
variable which is made available in the ApplicationEventsHolder.
Although this class is public, it is only intended for use within the
TCF or in the implementation of third-party extensions.
ApplicationEventsApplicationListener is responsible for listening to
all application events and recording them in the current
ApplicationEvents instance. A single
ApplicationEventsApplicationListener is registered with the test's
ApplicationContext by the ApplicationEventsTestExecutionListener.
The SpringExtension has also been updated to support parameters of type
ApplicationEvents via the JUnit Jupiter ParameterResolver extension
API. This allows JUnit Jupiter based tests to receive access to the
current ApplicationEvents via test and lifecycle method parameters as
an alternative to @Autowired fields in the test class.
Closes gh-25616
This new option allows a cancel signal to abort the request, which is
how we expect a connection to be aborted in a reactive chain that
involves the WebClient.
Closes gh-26287
This commit introduces computeAttribute() as an interface default method
in the AttributeAccessor API. This serves as a convenience analogous to
the computeIfAbsent() method in java.util.Map.
Closes gh-26281
Prior to this commit, the `NettyHeadersAdapter` would directly delegate
the `add()` and `set()` calls to the adapted
`io.netty.handler.codec.http.HttpHeaders`. This implementation rejects
`null` values with exceptions.
This commit aligns the behavior here with other implementations, by not
rejecting null values but simply ignoring them.
Fixes gh-26274
This commit makes sure that the matching pattern attributes is cleared
when an async result has been obtained, so that the subsequent
dispatch starts from scratch.
Closes gh-26239
This commit refines ConfigurationClassPostProcessor behavior in
native images by skipping configuration classes enhancement
instead of raising an error.
See spring-projects-experimental/spring-graalvm-native#248 for
more details.
Closes gh-26236
HttpMessageWriter implementations now attach the request log prefix
as a hint to created data buffers when the logger associated with
the writer is at DEBUG level.
Closes gh-26230
This commit updates websocket and messaging configurations in order
to not use CGLIB proxies anymore. The goal here is to allow support
in native executables and to increase the consistency across the
portfolio.
Closes gh-26227
The previous implementation uses ArrayList for storing resolved
resources and ArrayList has O(n) time complexity for the contains
operation. By switching to the HashSet for storing resolved
resources we improve the time complexity of this operation to be O(1).
See gh-25927
This commit improves the Javadoc for the `ForwardedHeaderFilter`
(Servlet Filter) and `ForwardedHeaderTransformer` (reactive variant) so
as to mention security considerations linked to Forwarded HTTP headers.
Closes gh-26081
Prior to this commit, the `SimpleApplicationEventMulticaster` would be
instrumented with the `ApplicationStartup` and start/stop events for
invoking event listeners (`spring.event.invoke-listener`).
This feature was already limited to single-threaded event publishers,
but is still flawed since several types of events can happen
concurrently. Due to the single-threaded nature of the startup sequence,
our implementation should not produce startup events concurrently.
This can cause issues like gh-26057, where concurrent events lead to
inconcistencies when tracking parent/child relationships.
This commit removes the `spring.event.invoke-listener` startup event as
a result.
Fixes gh-26057
This commit introduces AsyncServerResponse, an extension of
ServerResponse that is returned from ServerResponse.async and that
allows users to get the future response by calling the block method.
This is particularly useful for testing purposes.
This commit adds support for sending Server-Sent Events in WebMvc.fn,
through the ServerResponse.sse method that takes a SseBuilder DSL.
It also includes reference documentation.
Closes gh-25920
Remove the overriden pathVariable method from the nested request
wrapper,so that the merged attributes are used instead of the ones
provided by servlet.
Closes gh-26163
1. Revert changes in setHeader from 5.2.9 that caused regression on self-copy.
2. Update copyHeaders to ensure it still gets a copy of native headers.
3. Exit if source and target are the same instance, as an optimization.
Closes gh-26155
This commit introduces the following changes:
- Converters/codecs are now used based on generic type info.
- On WebMvc and WebFlux, kotlinx.serialization is enabled along
to Jackson because it only serializes Kotlin @Serializable classes
which is not enough for error or actuator endpoints in Boot as
described on spring-projects/spring-boot#24238.
TODO: leverage Kotlin/kotlinx.serialization#1164 when fixed.
Closes gh-26147
This commit only writes the 'charset' parameter in the written headers
if it is non-default (not UTF-8), since RFC7578 states that the only
allowed parameter is 'boundary'.
Closes gh-25885
Recently the Spring Framework projects could no longer be imported into
Eclipse IDE without compilation errors in JMH sources.
This commit addresses this issue by applying workarounds for bugs in
Gradle and the JMH plugin for Gradle.
Gradle bug: https://github.com/gradle/gradle/issues/14932
JMH plugin bug: https://github.com/melix/jmh-gradle-plugin/issues/157
The Gradle bug has already been fixed in Gradle 6.8 RC1; however, the
issue for the JMH plugin bug seems not to have been triaged yet.
Closes gh-26140
Despite the code duplication, we will not delegate to
AopUtils.invokeJoinpointUsingReflection() from
AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs().
The rationale is that the exception message in
invokeAdviceMethodWithGivenArgs() provides additional context via the
pointcut expression, and we would lose that additional context if we
simply delegate to AopUtils.invokeJoinpointUsingReflection(). We could
introduce an overloaded variant of invokeJoinpointUsingReflection() that
accepts an additional argument to provide the additional context for the
exception message, but we don't think that would be the best solution
for this particular use case.
In light of that, we are simply removing the TODO.
Closes gh-26126
Prior to this change the checks for isVariableName were duplicated
in 2 different locations. The logic has been moved to AspectJProxyUtils
to allow for re-use in those places and so that it benefits from any
optimizations that are done.
There are more locations which could benefit from not using a
toCharArray on a String, but rather use the charAt method from
the String itself. This to prevent an additional copy of the
char[] being created.
Prior to this commit, the promote task in the CI release pipeline would
write the "concourse-release-scripts" CONSOLE logs to /dev/null; this
commit ensures that we can read those while promoting artifacts.
gh-19930 introduced support for finding class-level test configuration
annotations on enclosing classes when using JUnit Jupiter @Nested test
classes, but support for @DynamicPropertySource methods got overlooked
since they are method-level annotations.
This commit addresses this shortcoming by introducing full support for
@NestedTestConfiguration semantics for @DynamicPropertySource methods
on enclosing classes.
Closes gh-26091
Prior to this commit, the test("test") conditions used in
AutowiredConfigurationErrorsIntegrationTests inadvertently asserted
that the invoked test methods reside in an org.springframework.test
subpackage, which is always the case for any test method in the
`spring-test` module. In other words, "test" is always a substring of
"org.springframework.test...", which is not a meaningful assertion.
This commit ensures that the JUnit Platform Test Kit is asserting the
actual names of test methods.
This commit introduces `and()` default methods in the MethodFilter and
FieldFilter functional interfaces in ReflectionUtils in order to simplify
uses cases that need to compose filter logic.
Closes gh-26063
Prior to this commit, a developer may have accidentally annotated a
JUnit Jupiter test method or lifecycle method with @Autowired, and that
would have potentially resulted in an exception that was hard to
understand. This is because the Spring container considers any
@Autowired method to be a "configuration method" when autowiring the
test class instance. Consequently, such an @Autowired method would be
invoked twice: once by Spring while attempting to autowire the test
instance and another time by JUnit Jupiter when invoking the test or
lifecycle method. The autowiring invocation of the method often leads
to an exception, either because Spring cannot satisfy a dependency (such
as JUnit Jupiter's TestInfo) or because the body of the method fails due
to test setup that has not yet been invoked.
This commit introduces validation for @Autowired test and lifecycle
methods in the SpringExtension that will throw an IllegalStateException
if any @Autowired method in a test class is also annotated with any of
the following JUnit Jupiter annotations.
- @Test
- @TestFactory
- @TestTemplate
- @RepeatedTest
- @ParameterizedTest
- @BeforeAll
- @AfterAll
- @BeforeEach
- @AfterEach
Closes gh-25966
The alternative is to use a filter but this makes it a little easier
and also guarantees that it will be downstream from all filters
regardless of their order, and therefore the Context will be visible
to all of them.
Closes gh-25710
In 5.3.x and forward, completely avoid logging unsent CONNECT messages
that are most likely authentication issues before the session is even
established.
Closes gh-26026
Adds a static INSTANCE to FullyQualifiedAnnotationBeanNameGenerator,
just like its parent class, AnnotationBeanNameGenerator, does.
The class doesn't have any state and overriding/hiding the INSTANCE of
the superclass, this prevents unintended use of a regular
AnnotationBeanNameGenerator through
FullyQualifiedAnnotationBeanNameGenerator.INSTANCE.
Prior to this commit, MergedAnnotationCollectors.toAnnotationSet()
created an intermediate ArrayList for storing the results prior to
creating a LinkedHashSet in the finishing step.
Since the creation of the intermediate list is unnecessary, this commit
simplifies the implementation of toAnnotationSet() by using the
Collector.of() factory method that does not accept a `finisher` argument.
The resulting Collector internally uses a `castingIdentity()` function
as the `finisher`.
Closes gh-26031
Prior to this commit, the findAllLocalMergedAnnotations() method in
AnnotationDescriptor altered between the use of TYPE_HIERARCHY and
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES for the SearchStrategy, depending
on @NestedTestConfiguration semantics; however, when searching for
"local" annotations, there is no need to search the enclosing class
hierarchy since AnnotationDescriptor#next() handles that use case.
This commit therefore switches to using only the TYPE_HIERARCHY
strategy.
This commit also discontinues the use of
MergedAnnotationCollectors.toAnnotationSet() in order to avoid the
unnecessary creation of a temporary List when collecting synthesized
annotations in a LinkedHashSet.
Closes gh-25985
This commit configures the logging level to DEBUG for the concourse
release scripts tasks.
This is useful to get a clue on where those long-running tasks are at.
With this commit, bean definition profiles declared via @ActiveProfiles
are once again stored in registration order, in order to support use
cases in Spring Boot and other frameworks that depend on the
registration order.
This effectively reverts the changes made in conjunction with gh-25973.
Closes gh-26004
This commit makes copies of the default headers and cookies when a
WebClient is built, so that subsequent changes to these do not affect
previously built clients.
Closes: gh-25992
Previous incarnation of MockMvc Kotlin DSL tried to reuse directly
Java APIs like ModelResultMatchers or StatusResultMatchers, but
when using multiple matchers in DSL blocks like model { } or
status { }, only the last statement was taken in account which
was very confusing.
This refactoring provides dedicated Kotlin DSLs for matchers.
The main API breaking changes is that functions like isOk() need to be
invoked with the parenthesis, isOk is not supported anymore (on purpose).
Closes gh-24103
Prior to this commit, if a developer accidentally copied and pasted the
same @ContextConfiguration or @TestPropertySource declaration from a
test class to one of its subclasses or nested test classes, the Spring
TestContext Framework (TCF) would merge the inherited configuration
with the local configuration, resulting in different sets of
configuration metadata which in turn resulted in a different
ApplicationContext instance being loaded for the test classes. This
behavior led to unnecessary creation of identical application contexts
in the context cache for the TCF stored under different keys.
This commit ignores duplicate configuration metadata when generating
the ApplicationContext cache key (i.e., MergedContextConfiguration) in
the TCF. This is performed for the following annotations.
- @ContextConfiguration
- @ActiveProfiles (support already existed prior to this commit)
- @TestPropertySource
Specifically, if @ContextConfiguration or @TestPropertySource is
declared on a test class and its subclass or nested test class with the
exact same attributes, only one instance of the annotation will be used
to generate the cache key for the resulting ApplicationContext. The
exception to this rule is an "empty" annotation declaration. An empty
@ContextConfiguration or @TestPropertySource declaration signals that
Spring (or a third-party SmartContextLoader) should detect default
configuration specific to the annotated class. Thus, multiple empty
@ContextConfiguration or @TestPropertySource declarations within a test
class hierarchy are not considered to be duplicate configuration and
are therefore not ignored.
Since @TestPropertySource is a @Repeatable annotation, the same
duplicate configuration detection logic is applied for multiple
@TestPropertySource declarations on a single test class or test
interface.
In addition, this commit reinstates validation of the rules for
repeated @TestPropertySource annotations that was removed when support
for @NestedTestConfiguration was introduced.
Closes gh-25800
This commit makes TransactionInterceptor and TransactionAspectSupport
Coroutines aware, adapting Reactive transaction support to Coroutines.
Suspending functions returning a Flow are handled like Flux, for other
return types, they are handled like Mono.
Closes gh-23575
This commit introduces TestContextAnnotationUtils as a replacement for
MetaAnnotationUtils, with dedicated support for honoring the new
@NestedTestConfiguration annotation and related annotation search
semantics.
MetaAnnotationUtils has been reverted to its previous scope and is now
deprecated.
See gh-19930
This commit introduces support for discovering @Sql, @SqlGroup,
@SqlConfig, and @SqlMergeMode on enclosing classes for @Nested test
classes in JUnit Jupiter.
Closes gh-25913
Includes forPayload methods and common adapter classes for programmatic usage.
Aligns default order values for event handling delegates to LOWEST_PRECEDENCE.
Closes gh-24163
The documentation written for the method WebSocketTransportRegistration.setSendTimeLimit(int timeLimit) mentions that, if no time limit is specified, a default value of 10 seconds is used; however, later on the exact default value employed is incorrectly typed as 10 * 10000 ms, which would result in 100 seconds instead.
The javadoc has been updated in order to show the correct value in milliseconds (10 * 1000).
This commit adds new tasks to the release pipeline, generating release
notes automatically using the issues in the current milestone and
pushing that as the content of the GitHub release.
Closes gh-25922
Prior to this commit only Propagation.NOT_SUPPORTED was supported for
disabling test-managed transactions via the `propagation` attribute of
`@Transactional`.
This commit allows users to specify Propagation.NOT_SUPPORTED or
Propagation.NEVER to disable test-managed transactions.
Closes gh-25909
This commit raises the minimum Coroutines version supported
to 1.4.0-M1 and above, and changes usages of awaitFirst() or
awaitFirstOrNull() to awaitSingle() or awaitSingleOrNull()
to fix gh-25007.
Closes gh-25914
Closes gh-25007
Prior to this commit, the EnclosingConfiguration mode used in
conjunction with @NestedTestConfiguration defaulted to INHERIT.
In other to allow development teams to change the default to OVERRIDE
(e.g., for compatibility with Spring Framework 5.0 through 5.2), this
commit introduces support for changing the default EnclosingConfiguration
mode globally via a JVM system property or via the SpringProperties
mechanism.
For example, the default may be changed to
EnclosingConfiguration.OVERRIDE by supplying the following JVM system
property via the command line.
-Dspring.test.enclosing.configuration=override
Closes gh-19930
Prior to this commit (and since Spring Framework 5.0), Spring's
integration with JUnit Jupiter supported detection of test
configuration (e.g., @ContextConfiguration, etc.) on @Nested classes.
However, if a @Nested class did not declare its own test configuration,
Spring would not find the configuration from the enclosing class. This
is in contrast to Spring's support for automatic inheritance of test
configuration from superclasses. The only workaround was to
copy-n-paste the entire annotation configuration from enclosing classes
to nested tests classes, which is cumbersome and error prone.
This commit introduces a new @NestedTestConfiguration annotation that
allows one to choose the EnclosingConfiguration mode that Spring should
use when searching for test configuration on a @Nested test class.
Currently, the options are INHERIT or OVERRIDE, where the current
default is OVERRIDE. Note, however, that the default mode will be
changed to INHERIT in a subsequent commit. In addition, support will be
added to configure the global default mode via the SpringProperties
mechanism in order to allow development teams to revert to the behavior
prior to Spring Framework 5.3.
As of this commit, inheritance of the following annotations is honored
when the EnclosingConfiguration mode is INHERIT.
- @ContextConfiguration / @ContextHierarchy
- @ActiveProfiles
- @TestPropertySource / @TestPropertySources
- @WebAppConfiguration
- @TestConstructor
- @BootstrapWith
- @TestExecutionListeners
- @DirtiesContext
- @Transactional
- @Rollback / @Commit
This commit does NOT include support for inheriting the following
annotations on enclosing classes.
- @Sql / @SqlConfig / @SqlGroup
In order to implement this feature, the search algorithms in
MetaAnnotationUtils (and various other spring-test internals) have been
enhanced to detect when annotations should be looked up on enclosing
classes. Other parts of the ecosystem may find the new
searchEnclosingClass() method in MetaAnnotationUtils useful to provide
similar support.
As a side effect of the changes in this commit, validation of user
configuration in repeated @TestPropertySource declarations has been
removed, but this may be reintroduced at a later date.
Closes gh-19930
This commit adds support for Kotlin Coroutines suspending functions to
Spring MVC, by converting those to a Mono that can then be handled by
the asynchronous request processing feature.
It also optimizes Coroutines detection with the introduction of an
optimized KotlinDetector.isSuspendingFunction() method that does not
require kotlin-reflect.
Closes gh-23611
Flow decoding is not supported yet since it depends on
kotlin/kotlinx.serialization#1073, but it will be
enabled when this issue will be fixed.
Closes gh-25771
The workaround was removed in the 5.3 milestone phase and in master
only because the referenced Jetty issue is marked fixed. However,
what we need to replace it with should be a little more involved
and also it's not entirely clear if the fixes in Jetty aligns with
our release and retain semantics so that needs to be investigated
more thoroughly.
Prior to this commit, the resource handler serving static resources for
Spring MVC and Spring WebFlux would always look at the
`Resource#lastModified` information, derive the `"Last-Modified"` HTTP
response header and support HTTP conditional requests with that
information.
In some cases, builds or packaging tools choose to set this last
modification date to a static date in the past. This allows tools to
have reproducible builds or to leverage caching given the static
resources content didn't change.
This can lead to problems where this static date (e.g. "1980-01-01") is
used literally in HTTP responses and will make the HTTP caching
mechanism counter-productive: the content of the resources changed, but
the application insists on saying it didn't change since the 80s...
This commit adds a new configuration option to disable this support -
there is no way to automatically discard those dates: there is no
standard for that and many don't use he "EPOCH 0 date" as it can lead to
compatibility issues with different OSes.
Closes gh-25845
Prior to this commit, error handlers in the WebMvc.fn and WebFlux.fn
router function builders had to be registered in an unintuitive, reverse
order, due to the filter chain composition model used.
This commit reverses the error handler order, so that more specific
error handlers can come before generic ones.
Closes gh-25541
This commit adds two overloaded methods for each HTTP method in the
WebFlux.fn and WebMvc.fn route builders: one method taking just a
handler function, the other a request predicate and handler function.
After this commit, it is no longer required to provide a String path,
which is particularly useful when nesting routes, and the path would be
"".
Closes gh-25752
This commit introduces a new async(Object) method in the WebMvc.fn,
taking a asynchronous response as argument in the form of a
CompletableFuture or Publisher. This allows for asynchronous setting
of headers and status (and not just body, which was already possible).
Closes gh-25828
Prior to this commit, the Series value for an HttpStatus was always
evaluated which resulted in an allocation of a Series array by invoking
Series.values() which makes a defensive copy.
This commit addresses this issue by hardcoding the corresponding Series
within the HttpStatus constructor, thereby avoiding any unnecessary
computations. In addition, a unit test has been added to verify that
all HttpStatus enum constants have a properly configured Series.
Closes gh-22366
The exchange() method is now deprecated because it is not safe for
general use but that doesn't apply to the WebTestClient because it
exposes a different higher level API for response handling that
ensures the response is consumed. Nevertheless WebTestClient cannot
call WebClient.exchange() any more.
To fix this WebTestClient no longer delegates to WebClient and thus
gains direct access to the underlying ExchangeFunction. This is
not a big deal because WebClient and WebTestClient do the same
only when it comes to gathering builder options and request input.
See gh-25751
This commit deprecates LiveBeansView and related classes in order to allow
a future removal in order to increase the separation of concerns between
Spring Framework and Spring Boot, and the consistency between JVM
and native.
Closes gh-25820
Now that there's a new JMH infrastructure for benchmarks and that
performance tests have been rewritten to use it, we should remove the
`PERFORMANCE` `TestGroup` to avoid introducing such tests in the future.
Closes gh-24830
Prior to this commit, some tests would belong to the PERFORMANCE
`TestGroup`, while they were not testing for performance but rather
performing functional tests that involve long running operations or
timeouts.
This commit moves those tests to the LONG_RUNNING `TestGroup`.
See gh-24830
Prior to this commit, the Asciidoctor Gradle tasks generated top-level
HTML and PDF documents for AsciiDoc files that are included in other
top-level documents. This causes slower builds and results in each
include-file being published twice:
1) inline in the including document (as intended)
2) as a top-level document but missing surrounding context (unintended)
The reason these include-files are generated as top-level documents is
that the asciidoctor and asciidoctorPdf Gradle tasks are configured to
use '*.adoc' as the input source files.
This commit addresses this issue by moving the following include-files
to new subdirectories. Locating the include-files in the subdirectories
causes them to be ignored in the '*.adoc' pattern used to identify
input source files.
- data-access-appendix.adoc -> data-access/data-access-appendix.adoc
- integration-appendix.adoc -> integration/integration-appendix.adoc
- testing-webtestclient.adoc -> testing/testing-webtestclient.adoc
Closes gh-25783
Prior to this commit, the asciidoctor Gradle task was configured to
generate both the HTML5 and PDF backends. Unfortunately, this resulted
in resources such as HTML, JavaScript, CSS, and images being published
alongside the generated PDF documents.
This commit addresses this issue by introducing the use of a dedicated
asciidoctorPdf Gradle task. The existing asciidoctor Gradle task has
been modified to only generate HTML5 output. Both of these tasks now
share common configuration supplied by the updated asciidoctorj Gradle
task.
In addition, the asciidoctor task now depends on the asciidoctorPdf
task. Thus, invoking `./gradlew asciidoctor` will still generate both
the HTML5 and PDF outputs; whereas, `./gradlew asciidoctorPdf` will
generate only the PDF outputs. We may later decide to rework the tasks
to introduce a dedicated asciidoctorHtml task so that we can generate
the HTML outputs without having to generate the PDF outputs (which are
more time consuming).
See gh-25783
This commit makes sure that exceptions emitted by WebClient are wrapped
by WebClientExceptions:
- Exceptions emitted by the ClientHttpConnector are wrapped in a new
WebClientRequestException.
- Exceptions emitted after a response is received are wrapped in a
WebClientResponseException
Closes gh-23842
This is done:
- For consistency with other Spring projects
- Because it is probably a better option to use reference instead of
spring-framework-reference (spring-framework is already present in
the URL)
- To improve PDF documentation discoverability
As a consequence:
- spring-framework-reference HTML documentation is now published
under reference/html
- spring-framework-reference/pdf PDF documentation is now published
under reference/pdf
The following permanent redirect should be created before Spring
Framework 5.3.0 release:
- current/spring-framework-reference/pdf/* to current/reference/pdf/*
- current/spring-framework-reference/* to current/reference/html/*
Closes gh-25071
See reactor/reactor-core#2374
All usages of this API are in tests, which are not checking overflow or
concurrent emissions - so a simple replacement with `try***` equivalents
is fine.
Prior to this commit, the subtype suffix of a MIME type (see RFC 6839)
was not properly taken into account when checking compatibility between
MIME types.
For example, `"application/*"` was not considered as compatible with
`"application/vnd.io.spring+json"`.
This commit adds a new `MimeType#getSubtypeSuffix()` method to easily
extract the subtype suffix information. This method is then reused in
the `isCompatibleWith` implementation to better handle these cases.
Fixes gh-25350
This commit deprecates the `AppCacheManifestTransformer` implementations
since the appcache feature is being removed from the browsers.
Closes gh-25733
Prior to this commit, the `GenericApplicationContext` configured the
`AppliationStartup` on the `BeanFactory` only right before refreshing it.
Delaying this has no purpose and we should instead configure it as soon
as possible by overriding the setter method.
Closes gh-25718
This commit makes several changes in both WebMvc.fn as well as
WebFlux.fn.
- ServerRequest now exposes a RequestPath through requestPath(), and
pathContainer() has been deprecated.
- The PathPredicate and PathResourceLookupFunction now respects this
RequestPath's pathInApplication() in their path-related
functionality.
- When nesting, the PathPredicate now appends the matched part of the
path to the current context path, instead of removing the matched
part (which was done previously). This has the same result: the
matched part is gone, but now the full path stays the same.
Closes gh-25270
Renaming the `tags` method to `getTags` for overall consistency, and
fixing the Javadoc to mention that this returns an immutable collection.
Closes gh-25678
MVC data class processor constructs target instance even in case of binding failure, as long as the corresponding method parameter is not marked as optional.
Closes gh-24372
Before this change messages were sent serially across sessions but
ordering is important only within a session. This leads to head of
line blocking when a session is slow to send, and also enforcement of
send buffer size and time limits is precluded because it happens at
a lower level in the transport.
This change ensures messages are held up only if there is another
from the same session is being sent. This allows messages from each
session to flow independent of other.
See gh-25581
Prior to this commit it was possible that a StartupStep was
started but never ended. This was the case when an exception
occured during bean initializing. To always call the method
regardless of the outcome, the call to StartupStep.end has
been moved to a finally block.
When an exception occurs the StartupStep is also enriched with
the exception class and message for diagnostic purposes.
See gh-22776
Closes gh-25572
Provides parity with similar options in MockMvc:
- compare header using a long value
- compare header using a date/time value
- dedicated method for "Location" header (redirect)
- let Hamcrest assert a header even when missing
See gh-19647
WebTestClient is an actual client and generally it's only possible
to assert the client response (i.e. what goes over HTTP). However,
in a mock server scenario technically we have access to the server
request and response and can make those available for further
assertions.
This will be helpful for the WebTestClient integration with MockMvc
where many more assertions can be performed on the server request
and response when needed.
See gh-19647
The original behavior was to ignore the body which came with odd
warnings in the Javadoc and potential leaks that could be reported
from tests causing unnecessary concern.
This change causes the body to be released and effectively still
ignores it but minus the potential leaks.
See gh-19647
The claimRequest method was not intended to be public and couldn't
have been used since the Info type it returned was package private.
This change completely hides the Info.
See gh-19647
This is the orginal "A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container". Here's an extra word of "otherwise".
This commit declares each of the following public interfaces as a
@FunctionalInterface.
- org.springframework.context.ApplicationContextInitializer
- org.springframework.test.web.servlet.DispatcherServletCustomizer
- org.springframework.validation.MessageCodeFormatter
- org.springframework.util.IdGenerator
- org.springframework.beans.factory.config.YamlProcessor.MatchCallback
- org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher
Closes gh-25580
Prior to this commit, MockHttpServletResponse's setCharacterEncoding()
method did not update the contentType property, which violates the
Servlet 2.4 Javadoc for getContentType() and setCharacterEncoding().
This commit addresses this issue; however, some existing tests may have
to be updated as a result of this change.
For example, note how some of the tests in this commit have been
refactored to use MediaType##isCompatibleWith() instead of asserting
exact matches for the value returned by MockHttpServletResponse's
getContentType() method.
Closes gh-25536
This commit removes the previously deprecated classes in Spring
Framework 5.2.x. By doing so, Spring Framework now requires RSocket
1.0+.
Closes gh-25548
This commit removes support for a standalone "L" in the
day-of-week of a cron expression, which used a locale-dependent
API to determine what the last day of the week is (Saturday or
Sunday ?).
Alternatively, we could have implement this in the exact way as Quartz
has done (i.e. treat the "L" like "SAT"), but we opted not to do that,
as having an explicit SAT or SUN is much clearer.
This commit makes sure that in CronExpression, the asterisk is only used
in a range field, and is not surrounded by unexpected characters.
Closes gh-19500
This commit introduces support for Quartz-specific features in
CronExpression. This includes support for "L", "W", and "#".
Closes gh-20106
Closes gh-22436
Added test for Friday 13th trigger, i.e. an uncommon crontab expression.
With the new CronExpression in place, this failure does not occur
anymore.
Closes gh-21574
Added test for a fixed day-of-week and day-of-month combination.
With the new CronExpression in place, this failure does not occur
anymore.
Closes gh-13621
Since reactor/reactor-netty#739, the `reactor-netty` module is now split
into two: `reactor-netty-core` and `reactor-netty-http`.
This commit updates the Spring Framework build accordingly.
- The compiler is configured to retain compatibility with Kotlin 1.3.
- Explicit API mode is not yet enabled but could be in the future.
- Some exceptions thrown by Kotlin have changed to NullPointerException,
see https://youtrack.jetbrains.com/issue/KT-22275 for more details.
Closes gh-24171
This commit adds a new `StartupStep` interface and its factory
`ApplicationStartup`. Such steps are created, tagged with metadata and
thir execution time can be recorded - in order to collect metrics about
the application startup.
The default implementation is a "no-op" variant and has no side-effect.
Other implementations can record and collect events in a dedicated
metrics system or profiling tools. We provide here an implementation for
recording and storing steps with Java Flight Recorder.
This commit also instruments the Spring application context to gather
metrics about various phases of the application context, such as:
* context refresh phase
* bean definition registry post-processing
* bean factory post-processing
* beans instantiation and post-processing
Third part libraries involved in the Spring application context can
reuse the same infrastructure to record similar metrics.
Closes gh-24878
In addition to the changes in
313a7836b0 to support passing on a
the underlying WebSocket message, this commits checks for its
availability.
Closes gh-25099
Prior to this commit, if the user supplied a comma-separated list such
as "en, it" as the Content-Language header value to
MockHttpServletResponse's setHeader() method, only the first language
was actually set in the response's Content-Language header (e.g., "en").
This commit ensures that all supplied content languages are set in the
response's Content-Language header.
Closes gh-25281
The recently introduced support for RSocketClient in commit
7c98251142 did not expose the underlying
client in order to avoid a hard dependency on RSocket 1.1 for the time
being. However such access appears to be necessary, e.g. for Spring
Integration, where the connection needs to be established (warmed up)
ahead of actual requests.
See gh-25332
* DestinationCache is now synchronized on multiple 'destination' locks
(previously a single shared lock)
* DestinationCache keeps destinations without any subscriptions
(previously such destinations were recomputed over and over)
* SessionSubscriptionRegistry is now a
'sessionId -> subscriptionId -> (destination,selector)' map
for faster lookups
(previously 'sessionId -> destination -> set of (subscriptionId,selector)')
closes gh-24395
Prior to this commit, The "auto grow" feature in SpEL expressions only
worked for element types with a default constructor. For example, auto
grow did not work for a list of BigDecimal elements.
This commit inserts a null value in the list when no default
constructor can be found for the element type.
Closes gh-25367
Because of security and broader industry support, support for several
remoting technologies is now deprecated and scheduled for removal in
Spring Framework 6.0.
This commit deprecates the following remoting technologies:
* HTTPInvoker
* RMI
* Hessian
* JMS remoting
Other remoting technologies like EJB or JAXWS might be deprecated in the
future depending on industry support.
Closes gh-25379
Remove convenience Map that is to avoid. The only downside is that
getHandlerMethods requires a transformation but that should not be used frequently.
See gh-22961
This commit evolves the solution from M1 by parsing and caching patterns with the
target HandlerMapping's PathPatternParser. This makes it unnecessary for callers to
be aware of pattern parsing.
Closes gh-25312
This commit introduces a way to change the PathPatternParser used in
PathPredicates, by way of a ChangePathPatternParserVisitor. This
visitor is used by both WebFluxConfigurationSupport and
WebMvcConfigurationSupport to make sure the configured parser is used.
Closes gh-23236
PR gh-358 introduced a "scheme but no host" check in the fromHttpUrl()
method in UriComponentsBuilder, but a similar check was not added to
fromUriString() at that time.
This commit introduces a "scheme but no host" check in fromUriString()
to align with the functionality in fromHttpUrl().
Note, however that the regular expressions used to match against the
hostname or IP address are inexact and still permit invalid host names
or IP addresses. True validation of the host portion of the URI is out
of scope for this commit.
Closes gh-25334
Using @SafeVarargs in Jackson mapper builder and factory bean classes
allows the varargs methods to be used without a compiler warning. The
implementations of these methods do not perform unsafe operations on
their varargs parameter. It is therefore safe to add this annotation.
The following two methods are changed:
- add @SafeVarargs to Jackson2ObjectMapperBuilder#modulesToInstall
and make it final
- add @SafeVarargs to
Jackson2ObjectMapperFactoryBean#setModulesToInstall and make it final
This is a backwards incompatible change as these methods now have to be
declared final. Existing subclasses that override one of these methods
will break.
Closes gh-25311
This commit removes the UndertowDataBuffer, in favor of using regular
DataBuffers from the DataBufferFactory. During the development of the
DefaultPartHttpMessageReader, it was determined that invoking various
slicing and releasing operators on the UndertowDataBuffer resulted in
memory leaks. This commit fixes that.
This commit introduces the DefaultMultipartMessageReader, a fully
reactive multipart parser without third party dependencies.
An earlier version of this code was introduced in fb642ce, but removed
again in 77c24aa because of buffering issues.
Closes gh-21659
This commit fixes a recent regression as a result of 5225a57411
with the determination of non-pattern vs pattern URLs. That in turn affects the ability to perform
direct matches by URL path.
There is also a fix in PathPattern to recognize "catch-all" patterns as pattern syntax.
See gh-24945
Prior to this commit the BeanPropertyRowMapper used
String.substring and String.toLowerCase to parse the
field names. This would generate more String than needed.
Instead one could iterate over the internal char[] of the
String and use the Character methods instead. This reduces
the String creation.
Closes gh-25301
List<T> support was added relatively late, incorrectly decoding each
part to T which means no way to decode a single part to List<T> and
thatis the most common case (vs multipart parts with the same name).
This behavior was further misaligned with Spring MVC as well as with
the behavior for T[].
Closes gh-22973
This commit removes load time weaving, CGLIB and Objenesis support
from native images.
GraalDetector has been removed for now because of
https://github.com/oracle/graal/issues/2594. It should be reintroduced
when this bug will be fixed with NativeImageDetector class name.
Closes gh-25179
As of reactor/reactor-core#2188, `DirectProcessor` variants are
deprecated. This commit replaces them with the new
`FluxIdentityProcessor` variant.
See gh-25085
This commit introduces a spring.xml.ignore system property
which when set to true avoid initializing XML infrastructure.
A typical use case is optimizing GraalVM native image footprint
for applications not using XML. In order to be effective, those
classes should be initialized at build time:
- org.springframework.util.DefaultPropertiesPersister
- org.springframework.core.io.support.PropertiesLoaderUtils
- org.springframework.web.servlet.function.support.RouterFunctionMapping
- org.springframework.web.client.RestTemplate
- org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
- org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
- org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
- org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
- org.springframework.http.codec.support.BaseDefaultCodecs
- org.springframework.beans.PropertyEditorRegistrySupport
Closes gh-25151
This commit introduces a spring.spel.ignore system property
which when set to true avoid initializing SpEL infrastructure.
A typical use case is optimizing GraalVM native image footprint
for applications not using SpEL. In order to be effective, those
classes should be initialized at build time:
- org.springframework.context.support.AbstractApplicationContext
- org.springframework.core.SpringProperties
- org.springframework.context.event.EventListenerMethodProcessor
Closes gh-25153
Prior to this commit, the Forwarded headers for Spring MVC and Spring
WebFlux did not support multiple prefix values for the
`"X-Forwarded-Prefix"` HTTP header.
This commit splits and processes multiple prefixes defined in the
dedicated header.
Closes gh-25254
Prior to this commit some of the default strategies defined
for the DispatcherServlet weren't included in the default
configuration for both Java and XML configuration.
The following default beans have been added to the configuration
with the name as expected by the DispatcherServlet:
- org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
- org.springframework.web.servlet.theme.FixedThemeResolver
- org.springframework.web.servlet.support.SessionFlashMapManager
- org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
Closes gh-25209
This commit introduces support for R2DBC ("Reactive Relational Database
Connectivity") with custom ConnectionFactory implementations, a
functional DatabaseClient for SQL execution, transaction management, a
bind marker abstraction database initialization utilities, and
exception translation.
Closes gh-25065
This commit introduces a change in reactive transaction semantics for
cancel signals. Canceling a subscription now rolls back a reactive transaction
to achieve a deterministic transaction outcome.
Previously, cancel signals committed a transaction which could
cause partially committed transactions depending on when the cancel happened.
With #25209, DispatcherServlet.properties loading and parsing
will be useless for most of use cases, and it requires
configuration on GraalVM native images.
The purpose of this issue to make such loading and parsing lazy,
only invoked in getDefaultStrategies() if needed.
Closes gh-25257
- The compiler is configured to retain compatibility with Kotlin 1.3.
- Explicit API mode is not yet enabled but could be in the future.
- A workaround for Gradle build is required for now, see
https://youtrack.jetbrains.com/issue/KT-39610 for more details.
- Some exceptions thrown by Kotlin have changed to NullPointerException,
see https://youtrack.jetbrains.com/issue/KT-22275 for more details.
Closes gh-24171
Prior to this commit, the JDBC KeyHolder API only supported keys of
type Number. However, a generated key can be a UUID or something else,
and developers shouldn't have to go manually through complex
collections to access it.
This commit adds a new getKeyAs(Class<T> keyType) method to the
KeyHolder API that allows the user to specify the key type.
Closes gh-24655
Prior to this commit, a change to Javadoc in any class in spring-core
would result in ALL tests in the entire test suite being re-run via the
Gradle build.
Thanks to a tip from @melix, this commit ensures that the spring-core
JAR is "reproducible".
Commit 4000b244ff introduced new variants for noNullElements in
org.springframework.util.Assert.
This commit adds the corresponding tests to AssertTests.
Closes gh-25239
Prior to this commit, Jaxb2XmlDecoder and XmlEventDecoder threw
XMLStreamExceptions instead of DecodingExceptions (as the Decoder
contract defines).
This commit resolves this issue.
Closes: gh-24778
Before this commit, Jackson2CodecSupport and subclasses
did not check media type encoding in the supportsMimeType
method (called from canEncode/canDecode).
As a result, the encoder reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
Closes: gh-25076
Before this commit, AbstractJackson2HttpMessageConverter and subclasses
did not check media type encoding in the canRead and canWrite
methods. As a result, the converter reported that it can write
(for instance) "application/json;charset=ISO-8859-1", but in practice
wrote the default charset (UTF-8).
This commit fixes that bug.
See: gh-25076
This commit avoids duplicate addition of void.class to the temporary
primitiveTypes Set in the static initialization block in ClassUtils.
Closes gh-25128
With a recent upgrade to an early access build for JDK 15,
ServerHttpsRequestIntegrationTests began failing since Netty's
SelfSignedCertificate could not be properly initialized.
This commit adds a test fixture dependency on BouncyCastle which is now
needed by Netty's SelfSignedCertificate on JDK 15 or higher, since JDK 15
no longer supports the javax.security.cert.X509Certificate.
See: https://bugs.openjdk.java.net/browse/JDK-8241039
Prior to this commit, calling the `setResponseBodyAdvice` method would
clear all existing `ResponseBodyAdvice` instances present in the list
before adding provided one.
This behavior is inconsistent with the Javadoc and other
implementations.
This brings the method in line with the existing documentation.
See gh-24204
In many places UrlPathHelper is created and used without any
customizations, in some cases repeatedly. This commit adds a
shared read-only UrlPathHelper instance with default settings.
See gh-25100
Prior to this commit (and the previous one), the `AntPathStringMatcher`
(inner class of `AntPathmatcher`) would compile `Pattern` instances and
use regex matching even for static patterns such as `"/home"`.
This change introduces a shortcut in the string matcher algorithm to
skip the `Pattern` creation and uses `String` equality instead.
Static patterns are quite common in applications and this change can
bring performance improvements, depending on the mix of patterns
configured in the web application.
In benchmarks (added with this commit), we're seeing +20% throughput
and -40% allocation. This of course can vary depending on the number of
static patterns configured in the application.
Closes gh-24887
Prior to this commit, `MediaType.parseMediaType` would already rely on
the internal LRU cache in `MimeTypeUtils` for better performance. With
that optimization, the parsing of raw media types is skipped for cached
elements.
But still, `MediaType.parseMediaType` would first get a cached
`MimeType` instance from that cache and then instantiate a
`new MediaType(type, subtype, parameters)`. This constructor not only
replays the `MimeType` checks on type/subtyme tokens and parameters, but
it also performs `MediaType`-specific checks on parameters.
Such checks are not required, as we're using an existing `MimeType`
instance in the first place.
This commit adds a new protected copy constructor (skipping checks) in
`MimeType` and uses it in `MediaType.parseMediaType` as a result.
This yields interesting performance improvements, with +400% throughput
and -40% allocation/call in benchmarks. This commit also introduces a
new JMH benchmark for future optimization work.
Closes gh-24769
Prior to this commit, the Spring Framework test suite would rely only on
"Performance" tests associated with a specific CI build. As outlined in
gh-24830, the way they're built and executed is not working well
anymore.
This commit introduces a new JMH benchmark infrastructure in the build.
The goal here is not to run those benchmarks as part of a CI build, but
rather provide a proper infrastructure for writing and locally running
micro-benchmarks when working on specific optimizations.
This commit adds and configures a Gradle JMH plugin to allow for JMH
benchmark classes in Spring Framework modules (in `src/jmh/java` of each
`spring-*` module). It's also relaxing the checkstyle rules for JMH
classes, especially around Javadoc rules: this code is not meant to
have Javadocs.
Finally, this commit links to a new Wiki page on the project GitHub
repository documenting the infrastructure and helping contributors to
run and design benchmarks.
See gh-24830
This commit avoids invoking StringBuilder.append(Object) in favor
of explicit method calls to append(String) and append(char) in
ContentDisposition.escapeQuotationsInFilename(String).
Closes gh-25056
This commit optimizes code in ResourceBundleMessageSource
by using computeIfAbsent instead of putIfAbsent.
In addition, the content of some Javadoc has been adjusted.
Closes gh-25054
Prior to this commit, if a BeanNameAutoProxyCreator was configured with
a custom TargetSourceCreator, the TargetSourceCreator was applied to
all beans in the ApplicationContext. Thus, the list of supported
beanNames was effectively ignored when applying any
TargetSourceCreator. Consequently, if a TargetSourceCreator returned a
non-null TargetSource for a given bean, the BeanNameAutoProxyCreator
proxied the bean even if the bean name had not been configured in the
beanNames list.
This commit addresses this issue by ensuring that a custom
TargetSourceCreator is only applied to beans whose names match the
configured beanNames list in a BeanNameAutoProxyCreator.
Closes gh-24915
Prior to this commit, the `VersionResourceResolver` implementations
would write a strong ETag HTTP response header with the resolved version
of the resource (the actual value depending on the chosen strategy).
This approach doesn't work well when combined with HTTP compression.
Web servers disable HTTP response copression in the presence of strong
ETags since mutating the response body would break the contract.
This commit changes this semantic and ensures that weak ETags are used
instead.
Closes gh-24898
Prior to this commit, patterns like `"/path/**/other"` would be treated
as `"/path/*/other"` (single wildcard, i.e. matching zero to many chars
within a path segment). This will not match multiple segments, as
expected by `AntPathMatcher` users or by `PathPatternParser` users when
in patterns like `"/resource/**"`.
This commit now rejects patterns like `"/path/**/other"` as invalid.
This behavior was previously warned against since gh-24958.
Closes gh-24952
This commit picks up where 613bd3be1d
left off by ensuring that a transaction manager configured via the
TransactionManagementConfigurer API takes precedence over any
transaction manager configured as a bean in the ApplicationContext
unless @Transactional is configured with a qualifier for the explicit
transaction manager to use in tests.
Closes gh-24869
When mutating a ServerHttpRequest or ClientResponse, the respective
builders no longer access cookies automatically which causes them to
be parsed and does so only if necessary. Likewise re-applying the
read-only HttpHeaders wrapper is avoided.
See gh-24680
Given that the body is a Flux<DataBuffer> there probably could be a
Flux<DataBuffer> body();
At least bodyToFlux(DataBuffer.class) which is used when mutating and
is a common case should not incur overhead.
See gh-24680
from() has the flaw of ignoring the body and it can't be fixed because
applications are guaranteed to be setting it already and if set twice
the builder drains the first body.
mutate() is a better fit in any case for what needs to be done in a
filter chain. It can be done more efficiently and is consistent with
similar options on the server side.
See gh-24680
Native server request headers have been wrapped rather than copied
since 5.1. This commit applies the same change to the client side
where, to make matters worse, headers were copied repeatedly on every
access, see also previous commit ca897b95.
For Netty and Jetty the wrappers are the same as on the server side
but duplicated in order to remain package private.
See gh-24680
Prior to this commit, the Spring TestContext Framework (TCF) favored a
@Primary transaction manger over one configured via the
TransactionManagementConfigurer API, and this contradicts the behavior
in production Spring applications.
This commit aligns the transaction manger lookup within the TCF so that
a transaction manger configured via the TransactionManagementConfigurer
API is properly favored over a @Primary transaction manager.
Closes gh-24869
This commit finishes the first step for migrating our complete build and
release pipeline to Concourse CI.
We're creating here a new "Release" jobs group in our pipeline.
We can now release Milestones from our pipeline with:
* the "stage-milestone" job, which creates and tags a new Milestone
version on the source repository, builds the artifacts and deploys them
in a staging repository and updates the version to the next SNAPSHOT.
* the "promote-milestone" fetches the build information from the staging
repository and promotes the released milestone in the official milestone
repository.
Interactions with the Artifactory and Bintray REST APIs are done using
the https://github.com/spring-io/concourse-release-scripts project.
Closes gh-22490
TransactionAttribute now exposes a labels attribute that associates a
descriptive array of labels with a transaction.
Labels may be of a pure descriptive nature or may get evaluated by
transaction managers to associate technology-specific behavior
with the actual transaction.
This commit introduces support for setting the
spring.test.constructor.autowire.mode property via a JUnit Platform
configuration parameter -- for example, via the
junit-platform.properties file.
Closes gh-24285
This commit makes the default ServerRequest implementation use a pre-
parsed path container, instead of parsing the path for each invocation
of pathContainer().
The `images` folder contains some files used to create the images, such
as OmniGraffle and SVG.
This commit modifies the `include` pattern to ensure that only `*.png`
files are copied from the source folder to the published reference
manual.
Since the spring-framework.png file is not used in the generated
reference manual, this commit moves the spring-framework.png file from
the src/docs/asciidoc/images folder up to the src/docs folder.
This commit ensures that the build directory exists before writing the
build scan URL to it. This is useful when the `clean` task is executed
and the build folder is gone by the time the execution is done.
See gh-22490
This commit introduces a test suite for ClientHttpConnector
implementations, as well as fixes that resolve issues identified by
these tests.
Closes gh-24941
Prior to this commit, the loadFactoryNames() and loadFactories() methods
in SpringFactoriesLoader effectively used a different default
ClassLoader.
This commit ensures that the ClassLoader for SpringFactoriesLoader.class
is now consistently used as the default ClassLoader.
Closes gh-24992
This commit ensures that the static cache in SpringFactoriesLoader
contains unmodifiable lists of unique names of factory implementations.
See gh-24985
This commit fixes the file pattern for the published zip artifacts.
Prior to this commit, the pattern was wrong and properties were not
applied to the published archives, preventing them from being published
automatically (javadoc, reference documentation, schemas...).
See gh-22490
Prior to this commit, SpringFactoriesLoader discovered all registered
factory implementations for a given factory type even if duplicates
were registered within a single META-INF/spring.factories file or in
multiple such files in the classpath.
This commit updates the internals of SpringFactoriesLoader so that
duplicate registrations are ignored, thereby aligning with the
well-known semantics for java.util.ServiceLoader in this regard.
Closes gh-24985
This commit updates the build pipeline to only run the checks
(formatting and tests) with the build when non-JDK8 variants are used
for sanity checks.
See gh-22490
- Build Scan plugin is now Gradle Enterprise plugin applied in settings
- Compile task dependencies are now defined through classpath
- Test fixture publication can be disabled through public API
Closes gh-24384
This commit adds the Concourse build infrastructure under the "ci/"
folder. It contains:
* "images/", the definitions of container images used in the pipeline
* "pipeline.yml" the build pipeline definition
* "parameters.yml" the parameters for the pipeline definition
* "tasks/" the tasks used by the build pipeline
* "scripts/" scripts used by pipeline tasks
This first iteration of the Concourse pipeline builds CI container
images for JDK8, JDK11, JDK14 and JDK15.
These images are used for building and publishing the master branch of
Spring Framework using JDK8. Other JDK variants are sanity checks and
don't actually publish the produced artifacts.
See gh-22490
As we're moving the build to Concourse CI, we don't need to use the
Artifactory plugin anymore. Our build will publish the artifacts to a
repository on the local filesystem and will push its content to
Artifactory with the spring-io/artifactory-resource.
This commit also adds the conditional configuration for publishing to a
local repository.
See gh-22490
Prior to this commit, BeanUtils.copyProperties() ignored generic type
information when comparing candidate source and target property types.
This commit reworks the implementation of BeanUtils.copyProperties() so
that generic type information is taken into account when copying
properties.
See gh-24281
This reverts commit ff65ccba3e.
Compiling against Groovy 3.0.3 currently results in the following two
warnings that cause the build to fail.
warning: Cannot find annotation method 'value()' in type 'SuppressFBWarnings': class file for edu.umd.cs.findbugs.annotations.SuppressFBWarnings not found
warning: Cannot find annotation method 'justification()' in type 'SuppressFBWarnings'
@@ -6,7 +6,7 @@ First off, thank you for taking the time to contribute! :+1: :tada:
* [Code of Conduct](#code-of-conduct)
* [How to Contribute](#how-to-contribute)
* [Discuss](#discuss)
* [Ask questions](#ask-questions)
* [Create an Issue](#create-an-issue)
* [Issue Lifecycle](#issue-lifecycle)
* [Submit a Pull Request](#submit-a-pull-request)
@@ -22,11 +22,10 @@ Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
### How to Contribute
#### Discuss
#### Ask questions
If you have a question, check Stack Overflow using
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest).
Find an existing discussion, or start a new one if necessary.
[this list of tags](https://stackoverflow.com/questions/tagged/spring+or+spring-mvc+or+spring-aop+or+spring-jdbc+or+spring-transactions+or+spring-annotations+or+spring-jms+or+spring-el+or+spring-test+or+spring+or+spring-remoting+or+spring-orm+or+spring-jmx+or+spring-cache+or+spring-webflux?tab=Newest). Find an existing discussion, or start a new one if necessary.
If you believe there is an issue, search through
[existing issues](https://github.com/spring-projects/spring-framework/issues) trying a
@@ -39,14 +38,18 @@ decision.
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. However,
before creating a ticket, please take the time to [discuss and research](#discuss) first.
before creating a ticket, please take the time to [ask and research](#ask-questions) first.
If creating an issue after a discussion on Stack Overflow, please provide a description
If you create an issue after a discussion on Stack Overflow, please provide a description
in the issue instead of simply referring to Stack Overflow. The issue tracker is an
important place of record for design discussions and should be self-sufficient.
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.2.x?groups=Build")
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
@@ -14,12 +14,20 @@ For access to artifacts or a distribution zip, see the [Spring Framework Artifac
## Documentation
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
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## Micro-Benchmarks
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
## Build from Source
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## Continuous Integration Builds
Information regarding CI builds can be found in the [Spring Framework Concourse pipeline](ci/README.adoc) documentation.
// TODO Uncomment link to JUnit 5 docs once we have sorted out
// the following warning in the build.
//
// warning: The code being documented uses packages in the unnamed module, but the packages defined in https://junit.org/junit5/docs/5.8.1/api/ are in named modules.
If you are using Eclipse 4.21, you will need to install
[Java 17 Support for Eclipse 2021-09 (4.21)](https://marketplace.eclipse.org/content/java-17-support-eclipse-2021-09-421)
from the Eclipse Marketplace.
## Steps
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Ensure that Eclipse launches with JDK 8.
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
1.Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
1.Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences → Java → Compiler → Errors/Warnings → Deprecated and restricted API → Forbidden reference (access rule)).
1.Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
1.Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
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).
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
1. Import all projects 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).
- 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 _three vertical dots_ 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-core` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
1.`spring-oxm` should be pre-compiled due to JAXB types generated for tests.
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
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
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.