This commit builds on top of changes made in gh-29775 and gh-31737.
Before this change, we would allocate several byte arrays even in cases
of known request size. This could decrease performance when getting the
cached content as it requires merging several arrays and data is not
colocated in memory.
This change ensures that we create a `FastByteArrayOutputStream`
instance with the known request size so that the first allocated segment
can contain the entire content.
If the request size is not know, we will default back on the default
allocation size for the `FastByteArrayOutputStream`.
Closes gh-31834
Refining the change from 43700302c6 so that
we consistently pick a PathPatternParser (a) if it is provided, and (b)
if both PathPatternParser and PathMatcher are not provided. Also applying
the same in the mutate builder.
See gh-31662
This commits allows ValueCodeGenerator$Delegate implementations to be
loaded from `META-INF/spring/aot.factories` and considered for code
generation of bean definition property values. This default behavior
in DefaultBeanRegistrationCodeFragments can be customized as usual.
Closes gh-31427
This commit introduces ValueCodeGenerator and its Delegate interface
as a way to generate the code for a particular value. Implementations
in spring-core provides support for common value types such a String,
primitives, Collections, etc.
Additional implementations are provided for code generation of bean
definition property values.
Closes gh-28999
Prior to this commit, the AnnotationsScanner used in the
MergedAnnotations infrastructure found duplicate annotations on methods
within multi-level interface hierarchies.
This commit addresses this issue by scanning methods at a given level
in the interface hierarchy using ReflectionUtils#getDeclaredMethods
instead of Class#getMethods, since the latter includes public methods
declared in super-interfaces which will anyway be scanned when
processing super-interfaces recursively.
Closes gh-31803
This commit matches the behavior of the core container when it
invokes a custom init or destroy method. If the custom method is an
interface implementation, the core container attempts to invoke the
method that's defined on the interface. This commit makes sure to also
register a hint for the interface method.
Closes gh-31819
Prior to this commit, the WebClient observations would have a specific
lifecycle where the observation context is build with a
`ClientRequest.Builder` as tracing needs to add an outgoing request
header before the request is made immutable.
With this setup, the metrics observation handler processes the start
event by increasing the "http.client.requests.active" counter and
collecting tags at this point. Because then the immutable request is not
yet fully built or set on the context, the keyvalues collected by the
observation convention at that point can be incomplete.
This commit ensures that a request is always made available in the
context, even if it is updated right after the observation start. The
only difference between the two should be additional tracing headers and
a request attribute holding the current observation context.
Closes gh-31702
This commit documents the fact that any (Unchecked)IOExceptions or
HttpMessageNotReadableExceptions thrown from the error handler will be
wrapped in a RestClientException.
Closes gh-31783
Prior to this commit, the `ConcurrentReferenceHashMap#restructure`
operation would null out the entire references array before starting the
restructuring operation (in case resizing is not necessary).
This could cause at runtime race conditions where a lookup operation
would return null, when the value is actually cached but not accesible
during the restructuring phase.
This commit ensures that, when resizing is not required, a new reference
list is built (purged of null entries) and then assigned to the
reference array. This way, concurrent reads will not return null for
existing entries and there are less chances of re-calculating cache
entries during the restructuring phase.
Closes gh-31008
Required by Spring Security to complete work on
https://github.com/spring-projects/spring-security/issues/14128
The setCache and resetCache methods used from createCacheFilter are now
public. Generally they don't need to be used outside of the Filter if
only making checks against the current request. Spring Security, however,
makes additional checks against requests with alternative paths.
Commit 33454a4007 introduced a regression in Comparators.nullsLow() and
Comporators.nullsHigh().
This commit updates the code so that nullsLow() sorts null values lower
than non-null values and nullsHigh sorts null values higher than
non-null values.
See gh-25478
Closes gh-31808
This commit adds ahead of time support for @Resource on fields and
methods. Lookup elements are discovered and code is generated to replace
that introspection at runtime.
Closes gh-29614
Introduce ShardingKeyDataSourceAdapter to get shard connections.
This commit introduces a DataSource proxy, that changes the behavior of the getConnection method to use the `createConnectionBuilder()` api to acquire direct shard connections. The shard connection is acquired by specifying a `ShardingKey` that is correspondent to the wanted shard.
While it is not easily possible to create a ConcurrentTaskScheduler
with no scheduled executor, DefaultManagedTaskScheduler has a default
constructor that does that as the JNDI lookup happens in the regular
afterPropertiesSet callback. If such an instance is created manually,
it can throw an unhelpful NullPointerException if one attempts to
schedule a task.
This commit updates ConcurrentTaskScheduler to flag that the scheduled
executor could be `null` and check if that's the case before using it.
This now throws a dedicated exception that should hopefully provide
better context for those upgrading.
See gh-27914
Closes gh-31751
This file is incomplete and has outdated content. Given that several
core committers are not even listed, it does not seem to serve a
valid purpose anymore.
Closes gh-31740
Previously, if an annotation processors was present in the classpath
it was executed as part of tests using `TestCompiler`.
This commit updates `TestCompiler` to always set the annotation
processors to use. By default, this sets an empty list which does not
use annotation processing.
Closes gh-31791
Includes special support for a read-only DataSource in addition to the regular target DataSource, avoiding the overhead of switching the Connection's read-only flag at the beginning and end of every transaction.
Closes gh-29931
Closes gh-31785
Closes gh-19688
Closes gh-21415
In gh-30549 we applied changes to the `DefaultPersistenceUnitManager` to
use the `ValidationMode.CALLBACK` to better detect invalid validation
setup and enforce bootstrap failures in those cases.
Unfortunately, doing so disables the detection of validation annotation
on entities during the schema creation phase. This is a known Hibernate
issue. This commit reverts this change until HHH-12287 is fixed.
Fixes gh-31726
This commit fixes a bug in DefaultPartHttpMessageReader's
MultipartParser, due to which the last token in a part window was not
properly indicated.
Closes gh-30953
Work performed in conjunction with gh-30941 resulted in a regression.
Specifically, prior to Spring Framework 6.1 a locally declared
@ComponentScan annotation took precedence over @ComponentScan
meta-annotations, which allowed "local" configuration to override
"meta-present" configuration.
This commit modifies the @ComponentScan search algorithm so that
locally declared @ComponentScan annotations are once again favored
over @ComponentScan meta-annotations (and, indirectly, composed
annotations).
See gh-30941 Closes gh-31704
Search for : assertThat\((.+).isEmpty\(\)\).isTrue\(\)
Replace with : assertThat($1).isEmpty()
Search for : assertThat\((.+).isEmpty\(\)\).isFalse\(\)
Replace with : assertThat($1).isNotEmpty()
Closes gh-31758
Search for : assertThat\((.+)\.equals\((\w+)\)\)\.isTrue\(\)
Replace with : assertThat($1).isEqualTo($2)
Search for : assertThat\((.+)\.equals\((\w+)\)\)\.isFalse\(\)
Replace with : assertThat($1).isNotEqualTo($2)
Closes gh-31763
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isTrue\(\)
Replace with : assertThat($1).contains($2)
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isFalse\(\)
Replace with : assertThat($1).doesNotContain($2)
Closes gh-31762
This commit partially reverts 39786e4790
and c5c843696b, as the approach taken did
not take into account request predicates that query request attributes,
including path variables.
Closes gh-31732
This commit introduces a toString() overload in
FastByteArrayOutputStream that accepts a Charset in order to mirror the
method that was introduced in ByteArrayOutputStream in JDK 10,
including a special case for when a single buffer is in use internally
to avoid the need to resize.
This commit also updates getContentAsString() in
ContentCachingRequestWrapper to use this new toString(Charset) method.
Closes gh-31737
This commit ensures that the RestClient uses the
IntrospectingClientHttpResponse to verify whether the response has a
body, and return null if it does not.
See gh-12671
Closes gh-31719
The getContentAsString method was originally added in d9b8826 to avoid
the extra copying inherent to calling ByteArrayOutputStream.toByteArray;
however, in f83c609 the class was updated to instead use
FastByteArrayOutputStream, and in the process the extra copy was brought
back when getContentAsString was changed to call toByteArray.
Switch to calling toByteArrayUnsafe, a method provided by
FastByteArrayOutputStream, which avoids the extra copy; since we
immediately pass the byte array to the String constructor, and it isn't
accessed anywhere else, the usage is safe.
See gh-31731
This commit allows to define a bean order programmatically
at bean definition level (functional equivalent of
`@Order`).
If specified, the order attribute defined at bean
definition level overrides potential values set with
`@Order`.
See gh-30849
Prior to this commit, regressions were introduced with gh-31417:
1. the observation keyvalues would be inconsistent with the HTTP response
2. the observation scope would not cover all controller handlers, causing
traceIds to be missing
The first issue is caused by the fact that in case of error signals, the
observation was stopped before the response was fully committed, which
means further processing could happen and update the response status.
This commit delays the stop event until the response is committed in
case of errors.
The second problem is caused by the change from a `contextWrite`
operator to using the `tap` operator with a `SignalListener`. The
observation was started in the `doOnSubscription` callback, which is too
late in some cases. If the WebFlux controller handler is synchronous
non-blocking, the execution of the handler is performed before the
subscription happens. This means that for those handlers, the
observation was not started, even if the current observation was
present in the reactor context. This commit changes the
`doOnSubscription` to `doFirst` to ensure that the observation is
started at the right time.
Fixes gh-31703
Fixes gh-31706
This commit updates MetadataNamingStrategy to quote an ObjectName
attribute value if necessary. For now, only the name attribute is
handled as it is usually a bean name, and we have no control over
its structure.
Closes gh-23608
This commit moves the condition used by `@DisabledInAotMode` to a
concrete implementation rather than using `@DisabledIf` as it causes
build initialization in a native image.
Closes gh-31705
This commit removes a list of hardcoded servers and version as this is
bound to get outdated and the reference guide/wiki is a more suitable
place for this.
This changes ensures RequestMappingInfo uses PathPatternParser by default
as all AbstractHandlerMapping implementations do as of 6.0.
RequestMappingInfo instances are typically created internally and aligned with
the RequestMappingHandlerMapping in terms of path mapping options.
If a RequestMappingInfo is registered programmatically, the caller needs to also
ensure they are aligned. However, if the two should be aligned by default.
Closes gh-31662
Prior to this commit, the TestContextManager logged an exception from a
TestExecutionListener at WARN level except in prepareTestInstance()
where such an exception was logged at ERROR level (except for a skipped
exception which is logged at INFO level).
For consistency, this commit modifies TestContextManager so that it
always logs non-skipped exceptions from TestExecutionListeners at WARN
level.
Closes gh-31688
This commit supports the scroll() and scroll(ScrollMode) methods from
Hibernate's Query API in SharedEntityManagerCreator's query-terminating
methods set.
Closes gh-31682
This commit makes sure to initialize any HandlerMapping defined in the
context when searching for resource handlers. Previously, the detection
algorithm was looking up for `SimpleUrlHandlerMapping` while the
declared target type in WebMvcConfigurationSupport is HandlerMapping.
If the application uses lazy initialization, the lookup algorithm would
not force that bean to be initialized.
Closes gh-25488
Prior to this commit, any time an aborted/skipped exception was thrown
by a TestExecutionListener, the TestContextManager unconditionally
logged the exception at WARN level -- or ERROR level for
prepareTestInstance() callbacks.
Regarding the latter, an aborted/skipped exception is certainly not an
ERROR, and in general the associated log output is very verbose
(including a stack trace) and not something the user should be warned
about it.
To improve the user experience, this commit revises TestContextManager
so that it logs such exceptions at INFO level.
Specifically, the following types of exceptions are considered
aborted/skipped exceptions.
- JUnit Jupiter: org.opentest4j.TestAbortedException
- JUnit 4 org.junit.AssumptionViolatedException
- TestNG: org.testng.SkipException
Closes gh-31479
The documentation currently states that Inversion of Control (IoC) and
Dependency Injection (DI) are the same thing. Although the two terms
are related, they are not synonymous: DI is a type of IoC.
I believe this change is important because using the terms
interchangeably really muddies the water about the meaning of these two
fundamental concepts of software frameworks.
Closes gh-31679
Prior to this commit, `ExchangeFilterFunction` could only get the
current observation from the reactor context. This is particularly
useful when such filters want to add KeyValues to the observation
context.
This commit makes this use case easier by adding the context of the
current observation as a request attribute. This also aligns the
behavior with other instrumentations.
Fixes gh-31609
The JDBC API that retrieves a proedure or a function allows to specify
patterns for the schema and the procedure name. So far, we've called
this API with the value as is, which does not work if either contains
a wildcard characters that need to be escaped.
This commit updates GenericCallMetadataProvider to escape, if necessary,
the schema or procedure name using the search string escape from the
database metadata.
Closes gh-22725
Prior to this commit, AspectJExpressionPointcut doesn't fall back to original method if `!@annotation()` is used, it can cause false positive result.
Fix GH-27119
Prior to this commit, the Jackson 2.x encoders, in case of encoding a
stream of data, would first release the `ByteArrayBuilder` and then the
`JsonGenerator`. This order is inconsistent with the single value
variant (see `o.s.h.codec.json.AbstractJackson2Encoder#encodeValue`) and
invalid since the `JsonGenerator` uses internally the
`ByteArrayBuilder`.
In case of a CSV Encoder, the codec can buffer data to write the column
names of the CSV file. Writing an empty Flux with this Encoder would not
fail but still log a NullPointerException ignored by the reactive
pipeline.
This commit fixes the order and avoid such issues at runtime.
Fixes gh-30493
This commit fixes a regression introduced by gh-21139
via the usage of Kotlin reflection to invoke HTTP
handler methods. It ensures that kotlin.Unit is treated
as void by returning null.
It also polishes CoroutinesUtils to have a consistent
handling compared to the regular case, and adds related
tests to prevent future regressions.
Closes gh-31648
Includes removal of evict step on pipeline exception, retaining a previous cache value and avoiding an incomplete key (for consistency with non-reactive caching).
Closes gh-31626
This commit extract spring-related links and recurring external links
into asciidoctor attributes to be used by the Antora toolchain.
It notably homogenizes links to:
- IETF RFCs
- Java Community Process JSRs
- the Java API Documentation (on the Java 17 version)
- Kotlin documentations (on the Kotlinlang.org version)
- the Spring Boot reference guide (on the `html` version)
This commit also reworks most link attributes to follow a
Project-Category-Misc syntax. For example, `spring-boot-docs` rather
than `docs-spring-boot`.
Finally, it makes an effort to clean up remainders from the previous
documentation toolchain, namely the `docs/asciidoc` folder and
`modules/ROOT/pages/attributes.adoc` file.
Closes gh-26864
Closes gh-31619
In order to prevent leaks of large amounts of non-heap
memory (and potential other efficiency and performance side
effects), this commit updates ResourceUtils#useCachesIfNecessary
to leave the caching flag to its JVM default value for instances
of JarURLConnection.
The previous behavior was originally introduced via gh-9316 and
gh-13755 to avoid I/O failure during webapp hot reloading in
Servlet containers. This is not a popular deployment mode anymore
and we have not been able to reproduce the original issue with
a Java 17 JVM and Tomcat 10.
Closes gh-30955
Legacy EJB attributes are ignored since 6.0 due to being bound to a plain JndiObjectFactoryBean - but can still be declared now, e.g. when validating against the common versions of spring-jee.xsd out there.
Closes gh-31627
The description is for WebFlux, but the link points to WebFlux unit
testing support.
This commit changes the link to point the the WebFlux chapter.
Closes gh-31632
Adding generated code in the default package is not supported as we
intend to import it, most probably from another package, and that is
not supported. While this situation is hard to replicate with Java,
Kotlin is unfortunately more lenient and users can end up in that
situation if they forget to add a package statement.
This commit checks for the presence of a valid package, and throws
a dedicated exception if necessary.
Closes gh-31628
Prior to this commit, the getResource() methods in PathResourceResolver
implementations allowed an exception thrown from Resource#getURL() to
propagate instead of logging a warning about the missing resource as
intended.
This commit modifies the getResource() methods in PathResourceResolver
implementations so that the log messages include the output of the
toString() implementations of the underlying resources instead of their
getURL() implementations, which may throw an exception.
Furthermore, logging the toString() output of resources aligns with the
existing output for "allowed locations" in the same log message.
Note that the toString() implementations could potentially also throw
exceptions, but that is considered less likely.
Closes gh-31623
This commit makes sure that the per-operation execution context for
caching and event listening does not recreate the default internal
delegates, but rather get initialized with a shared state.
This reduces the number of instances created per operation execution,
reducing the GC pressure as a result. This also makes sure that any
cache, such as the one in StandardTypeLocator, is reused.
Closes gh-31617
This commit introduces a ConvertibleClientHttpResponse type that
extends ClientHttpResponse, and that can convert the body to a desired
type. Before this commit, it was not easy to use the configured HTTP
message converters in combination with RestClient::exchange.
Closes gh-31597
This commit allows to terminate the JVM when the
-Dspring.context.exit=onRefresh property is set,
which can be useful for AppCDS training run in order
to get most of the AppCDS cache without starting the
beans.
Closes gh-31595
This commit adds a link in the package-overview pages of KDoc and
Javadoc, pointing to the other documentation's own page.
In order for local tests to work, the build has been slightly modified
to align with the directory structure in the distributed documentation
zip (and consequently with that of the deployed documentation website).
Lastly, the javadoc build was fixed to include the `overview.html` again
in the resulting HTML index, since this is where the KDoc link is added.
See gh-28055
Closes gh-31587
This commit clarifies that the annotation is used to capture events that
are fired from the test `Thread` or descendant threads, since the test
framework uses `InheritableThreadLocal` to store captured events now.
See gh-31079
See gh-30020
This commit ensures that not every OutputStream.write gets written as a
separate chunk, by buffering the written data in a BufferedOutputStream.
In some cases, a large quantity of small writes would result in many
sent chunks.
Closes gh-31361
Prior to this commit, the JMS listener observations would only cover the
actual listener invocation, but not the error handling phase. This means
that all errors (including the handled ones) are marked as errors in the
observation and that the observation is not current anymore when error
handling happens.
This commit aligns the behavior with the other Spring Framework
instrumentations and ensures that the error handling phase is fully part
of the observation recording.
Closes gh-31559
This commit updates PersistenceManagedTypesBeanRegistrationAotProcessor
to register reflection hints for `@EmbeddableInstantiator` annotations
available as of Hibernate 6.0 when needed.
Related tests will be added in
https://github.com/spring-projects/spring-aot-smoke-tests.
Closes gh-31534
Allows Kotlin caller to get a non-nullable property,
using a default value when the property is not set.
A method already exists on PropertyResolver which does this,
but takes a Class parameter.
The extension method can eliminate the parameter via reified type,
similar to the other extension methods which exist already.
Closes gh-31523
This commit documents that the "error" key in Micrometer Observations
should be preferred over the legacy "exception" one. Right now the
information is duplicated but we might remove the deprecated one in the
future.
Closes gh-31514
This commit ensures that the StreamingHttpOutputMessage.Body.repeatable
flag is set in message converters for bodies that can be written
repeatedly.
Closes gh-31516
See gh-31449
This reverts commit 93206c3f6e and updates
the related test to only rely on the fact the compiler fails. Relying
on a message will not work and the status code can be implementation
independent according to its javadoc.
Closes gh-31536
The me.champeau.mrjar Gradle plugin causes non-existent libraries to be
added to the Eclipse classpath, such as:
<classpathentry kind="lib" path="/workspaces/spring-framework/spring-core/build/classes/kotlin/java21">
<attributes>
<attribute name="gradle_used_by_scope" value="java21"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
This results in build errors in Eclipse IDE like the following.
Project 'spring-core' is missing required library:
'/workspaces/spring-framework/spring-core/build/classes/kotlin/java21'
This commit filters those and removes them.
Commit d3fba6d49b introduced built-in pattern matching support for
method names in ControlFlowPointcut; however, it was still cumbersome
to extend ControlFlowPointcut with support for regular expressions
instead of simple pattern matching.
To address that, this commit introduces a variant of isMatch() that
accepts the pattern index instead of the pre-resolved method name
pattern. The default implementation retrieves the method name pattern
from the methodNamePatterns field and delegates to isMatch(String, String).
Subclasses can override the new isMatch(String, int) method to support
regular expressions, as can be seen in the example
RegExControlFlowPointcut class in ControlFlowPointcutTests.
See gh-31435
This commit fixes code generation when an indexed constructor argument
value is null as the method is overloaded and need the value to be
cast to `Object`.
Closes gh-31508
Prior to this commit, ControlFlowPointcut supported a single method
name which was matched exactly. Although it was possible to extend
ControlFlowPointcut to add support for pattern matching, it was a bit
cumbersome.
To address that, this commit introduces built-in pattern matching
support for method names in ControlFlowPointcut, analogous to the
pattern matching support in NameMatchMethodPointcut.
Specifically, a user can provide one or more method name patterns, and
the patterns will be matched against candidate method names using OR
semantics.
By default, the matching algorithm delegates to
PatternMatchUtils.simpleMatch(), but this can be overridden in
subclasses by overriding the new protected isMatch() method.
Closes gh-31435
Previously, ConstructorResolver would reject any candidate if the
parameter is `null`. The reason for that is that null does not carry
any type and the matching algorithm would systematically fail for that
argument.
This commit adds an extra check, and several tests, to validate that
a null value is taken into account.
Closes gh-31495
Prior to this commit, @SpringJUnitConfig and @SpringJUnitWebConfig
did not declare `loader` attributes that alias @ContextConfiguration's
`loader` attribute. Consequently, it was not possible to configure a
custom ContextLoader via those annotations.
The lack of those `loader` attributes was an oversight, and this commit
introduces them to support custom ContextLoader configuration directly
via the @SpringJUnitConfig and @SpringJUnitWebConfig annotations.
Closes gh-31498
This commit surfaces the ETag generation feature for both
`ResourceHttpRequestHandler` and `ResourceWebHandler` on their
respective `ResourceHandlerRegistration` for easier configuration.
See gh-29031
This commit makes ControlFlowPointcut more open to subclasses by:
1. Making the ControlFlowPointcut#clazz field protected.
2. Making the ControlFlowPointcut#methodName field protected.
3. Introducing a protected incrementEvaluationCount() method.
Closes gh-27187
This commit introduces the maxParts and maxPartSize properties to
PartEventHttpMessageReader, which can be used to limit the amount of
parts, and maximum part size respectively.
Closes gh-31343
Previously the documentation assumed that the readers knew how to use
the X-Forwarded-* headers. This commit documents details & examples
of how to use the X-Forwarded-* headers.
See gh-31491
Since we do not yet have support for registering resource hints for
classpath location patterns, we have decided to explicitly skip such
resources and log a warning to inform users that they need to manually
supply resource hints for the exact resources needed by their
application.
This commit applies this change for @PropertySource and
@TestPropertySource.
See gh-31162
Closes gh-31429
This commit harmonizes AnnotationDrivenBeanDefinitionParser so that it
does not instantiate a property value while parsing the element. Rather,
it creates an inner bean definition so that the property is created
during the refresh phase.
Closes gh-31472
This commit refines MaxUploadSizeExceededException
handling in order to translate to a "413 Payload Too Large"
status code instead of "500 Internal Server Error", with
related ProblemDetail body.
Closes gh-27170
Prior to this commit, the `ResourceHttpRequestHandler` would support
HTTP caching when serving resources, but only driving it through the
`Resource#lastModified()` information.
This commit introduces an ETag generator function that can be configured
on the `ResourceHttpRequestHandler` to dynamically generate an ETag
value for the Resource that is going to be served.
Closes gh-29031
This commit improves the exception that is thrown when a particular
source class cannot be parsed. Previously, the message would include
the root configuration class, which may not be the class that
actually failed as parsing can trigger component scan. There's now
a dedicated catch that generates an exception message that includes the
class that is currently parsed.
Closes gh-31146
We can't upgrade to Eclipselink 4 as it would change the baseline that
this generation uses. However, there is a recent release in the current
line that adds compatibility with recent JDKs.
See gh-31078
This commit removes the "plain old class" bit of the documentation as
it may be confusing. The gist of it is that it must be a bean but not
annotated with `@Configuration` so the updated sentence states exactly
that.
Closes gh-29957
This commit introduces additional tests for "quoted identifier" support
in SimpleJdbcInsert when the schema itself is defined using quoted
identifiers -- for example, to use keywords as column names.
See gh-31208
This commit improves the handling of IllegalArgumentException in
SimpleInstantiationStrategy. Previously, only arguments mismatch were
handled but the exception can also be thrown if the factory instance
does not match the target method.
Closes gh-28897
This commit adds a test and polishing for a change in
AbstractNamedValueMethodArgumentResolver erroneously committed
with (unrelated) commit e57b942b.
If an argument becomes null after conversion and a default value is
applied, that default value should also pass through conversion.
Closes gh-31336
This commit adds a repeatable property to
StreamingHttpOutputMessage.Body, indicating that the body can be written
multiple times. In HttpComponentsClientHttpRequest, this property is
exposed via org.apache.hc.core5.http.HttpEntity.isRepeatable, to allow
for redirects.
Closes gh-31449
Prior to this commit, configuring a Servlet filter in MockMvc with a
defined mapping would only consider "/*" as a catch-all pattern.
This commit relaxes this rule by also accepting "*" mappings.
Closes gh-28041
This commit re-generates the protobuf Java classes with a recent version
of the protoc binary and adds JMH benchmarks that exercise the message
converter for both the reading and writing cases.
See gh-29496
Use the helper to reduce logging when an @ExceptionHandler fails
to write to the response due to a network failure where the client
has gone away.
Closes gh-26181
Prior to this commit, the NestedTestCase resulted in errors during our
AOT end-to-end integration tests since it did not comply to our "*Tests"
naming convention.
See gh-29122
This commit applies @DisabledInAotMode to test classes in the
spring-test module that will never be able to be processed for AOT
optimizations.
Test classes that fail for reasons that can potentially be addressed in
a future version of the framework have not been annotated with
@DisabledInAotMode.
See gh-29122
Although it should not happen in theory, sometimes a test class is
discovered more than once via the TestClassScanner in our integration
tests. When it does happen in our tests, the two Class objects have the
same fully-qualified class name but represent different classes which
leads to failures due to incorrect associations between test class
names and their MergedContextConfiguration.
To address this, this commit modifies TestContextAotGenerator so that
it skips duplicate test class names.
This commit adds Coroutines support for `@Cacheable`.
It also refines SimpleKeyGenerator to ignore Continuation
parameters (Kotlin does not allow to have the same method
signature with both suspending and non-suspending variants)
and refines
org.springframework.aop.framework.CoroutinesUtils.awaitSingleOrNull
in order to wrap plain value to Mono.
Closes gh-31412
This commit introduces @DisabledInAotMode in the TestContext
framework to support the following use cases.
- Disabling AOT build-time processing of a test ApplicationContext --
applicable to any testing framework (JUnit 4, JUnit Jupiter, etc.).
- Disabling an entire test class or a single test method at run time
when the test suite is run with AOT optimizations enabled -- only
applicable to JUnit Jupiter based tests.
Closes gh-30834
This commits makes sure that a bean that produces an array can be
processed ahead of time. If the request target type is an array, its
component type is used.
Closes gh-31426
This commit improves compatibility with the core container when running
in AOT mode by adding support for generic constructor argument values.
Previously, these were ignored altogether. We now have code generation
support for them as well as resolution that is similar to what
AbstractAutowiredCapableBeanFactory does in a regular runtime.
This commit also improves AOT support for XML bean configurations by
adding more support for TypedStringValue and inner bean definitions.
Closes gh-31420
Since the Spring WebFlux HTTP server instrumentation has been moved from
the `WebFilter` to the `HttpWebHandlerAdapter`, we need to apply similar
changes there.
See gh-31417
This commit adds support for TypeStringValue when generating AOT code.
If the value does not specify an explicit type, it's specified as is.
Otherwise, the TypeStringValue instance is restored via the appropriate
code generation.
Closes gh-29074
This commit reintroduces a deprecated ReactorResourceFactory in
org.springframework.http.client.reactive package that extends
the one in org.springframework.http.client package to avoid an
API breaking change and to provide a smoother upgrade experience.
Closes gh-31399
This commit is a best effort attempt at identifying the members that
code generation invokes and might be deprecated. It introduces
a CodeWarnings helper class that records warnings, with special
handling for `@Deprecated`.
See gh-29597
This commit is a prerequisite to help suppressing deprecating warnings
by allowing tests to validate that the compiler does not encounter them.
See gh-29597
In AbstractApplicationEventMulticaster.retrieveApplicationListeners,
despite best efforts to avoid it, unwrapped proxies (singleton targets)
can end up in the list of programmatically registered listeners. In
order to avoid duplicates, we need to find and replace them by their
proxy counterparts, because if both a proxy and its target end up in
'allListeners', listeners will fire twice.
Fixes#28283.
This commit adds a constructor with externally managed
Reactor Netty resources to ReactorNettyClientRequestFactory
and makes it lifecycle-aware in order to support Project CRaC.
Closes gh-31280
Closes gh-31281
Prior to this commit, the bean definition properties code generator
would register hints for invoking the setter methods of registered
property values defined for the bean definition.
The internal algorithm is also reflecting on the Field to discover
annotations. Doing so actually calls `getDeclaredFields` to iterate on
the available fields. This is done recursively up the type hierarchy
until the field is found.
This commit registers the required reflection metadata.
Closes gh-31390
This commit revises the previous commit as follows.
- Remove hasTestMethod() from TestContext and instead introduce a new
variant of createDelegatingTransactionAttribute() in
TestContextTransactionUtils which accepts a boolean
`includeMethodName` flag.
- Add missing @TestMethodOrder declaration to
AfterTestClassSqlScriptsTests to ensure that the test methods are
always executed in the required order.
- Polish Javadoc and add missing @since tags.
Closes gh-27285
This commit replaces uses of onErrorResume() with
- onErrorMap() in places where onErrorResume() is just used to map to a
different exception.
- onErrorComplete() where onErrorResume() just maps to Mono.empty().
- onErrorReturn() where onErrorResum() just maps to Mono.just().
Closes gh-31352
This commit removes the previously introduced reflection hints that were
working around known issues in GraalVM.
Spring Framework 6.1 will require recent maintenance versions of GraalVM
and should not contribute such hints anymore.
Closes gh-30394
Prior to this commit, the bean registration AOT contributions would
register introspection and invocation hints on both declared and public
methods for bean types. The bean introspection algorithm also looks at
default methods implemented by interfaces when collecting bean property
information.
This commit ensures that introspection hints are registered for all
implemented interfaces when registering beans.
Closes gh-31350
This commit partially reverts 3b8dd0a5, which introduced a strict
validation in JmsAccessor#setSessionAcknowledgeMode that prevents use
of vendor-specific acknowledge modes.
See gh-31328
This commit introduces initialize() methods in
AbstractRoutingDataSource and AbstractRoutingConnectionFactory as an
alternative to invoking afterPropertiesSet().
Closes gh-31248
Prior to this commit, DefaultJdbcClient updated the supplied KeyHolder
when using named parameters but not for positional parameters.
This commit refactors the creation of the
PreparedStatementCreatorFactory so that the PreparedStatementCreator
properly creates a PreparedStatement which returns generated keys.
Closes gh-31297
Prior to this commit, the `BeanRegistrationsAotContribution` would only
contribute introspection hints for declared methods. This does not cover
inherited public methods.
This commit adds the missing hint on public methods.
Fixes gh-31293
This commit configures the Foojay resolver plugin in the Gradle build in
order to auto-provision a required JDK distribution if it's not present
already on the host.
Currently the Spring Framework build requires both a JDK 17 and a JDK 21
distribution to build artifacts.
Closes gh-30474
Prior to this commit, `DisposableBeanAdapter` supported reactive bean
destroy methods by detected if `Publisher` is available on the
classpath. The AOT engine did not contribute a reflection hint for this
call.
This commit ensures that this reflection hint is registered in all
cases, even if there are no destroy methods detected on beans.
Fixes gh-31278
`PathMatchingResourcePatternResolver` is reflecting on
`org.eclipse.core.runtime.FileLocator` and invoking methods on it for
OSGi support. While this use case is highly unlikely in native images,
registering the reflection entry by itself should be enough.
Fixes gh-31271
This commit adds the relevant reflection hints required by
`KotlinDetector`; this class is trying to detect both `kotlin.Metadata`
and `kotlin.reflect.full.KClasses`.
Fixes gh- 31269
This commit adds reflection hints for `jakarta.inject.Provider` and
ensures that hints are always contributed even if jakarta classes are
not on the classpath.
Fixes gh-31259
Prior to this commit, `ClassUtils#forName` would always attempt to
resolve the given class name as a nested type. For example, searching
for `org.example.Spring` would try to resolve:
* `org.example.Spring`
* if not available, try `org.example$Spring` as well
Java classes usually start with uppercase letters, so this additional
lookup can be costly and not very useful.
This commit only attempts nested class lookups when the previous segment
starts with an uppercase. So `org.example.Spring.Issue` will look for
`org.example.Spring$Issue`, but `org.example.Spring` will not.
Closes gh-31258
Except for meaningful double spaces (for example, to align the
indentation of comments), this commit replaces all unnecessary double
spaces with single spaces in the spring-webmvc module.
Closes gh-31245
Prior to this commit in the message converters it was possible
to set a pre-configured ObjectMapper. However the constructor
would still create and configure an ObjectMapper.
With the added constructor it is now possible to directly
construct the message converter with the proper ObjectMapper.
This prevents the this additional ObjectMapper to be constructed.
send(..) -methods of JavaMailSenderImpl which is only delegating to
other methods are pulled up as default methods in the interfaces
JavaMailSender and MailSender, to make these interfaces require fewer
methods to implement.
See gh-23651
Prior to this commit, it was only possible to register a
ContextCustomizerFactory in the TestContext framework (TCF) via the
SpringFactoriesLoader mechanism.
This commit introduces support for declarative registration of a
ContextCustomizerFactory local to a test class via a new
@ContextCustomizerFactories annotation.
Closes gh-26148
In light of the refinements to ObjectUtils, this commit updates
SynthesizedMergedAnnotationInvocationHandler to use
ObjectUtils.nullSafeHashCode() and removes the now obsolete code in
SynthesizedMergedAnnotationInvocationHandler.
See gh-29051
This commit reverts the deprecation of CommandLinePropertySource and
SimpleCommandLinePropertySource, since we have discovered that Spring
Boot actively uses SimpleCommandLinePropertySource in
org.springframework.boot.SpringApplication.
Closes gh-31207
This commit deprecates the various nullSafeHashCode methods taking array
types as they are superseded by Arrays.hashCode now. This means that
the now only remaining nullSafeHashCode method does not trigger a
warning only if the target type is not an array. At the same time, there
are multiple use of this method on several elements, handling the
accumulation of hash codes.
For that reason, this commit also introduces a nullSafeHash that takes
an array of elements. The only difference between Objects.hash is that
this method handles arrays.
The codebase has been reviewed to use any of those two methods when it
is possible.
Closes gh-29051
This commit revises the contribution for gh-25921 in the following ways.
- Use instanceof pattern matching
- Use List.of() and Map.of()
- Add missing @since tags
- Polish Javadoc
- Rename isNegativeNumber() to isNegativeNumberLiteral()
- Restructure InlineCollectionTests using @Nested, etc.
- Fix testListWithVariableNotCached() test: it previously set a SpEL
"variable" but tested a "property" in the root context object, which
effectively did not test anything.
- Introduce additional tests: listWithPropertyAccessIsNotCached(),
mapWithVariableIsNotCached(), and mapWithPropertyAccessIsNotCached().
This commit changes the way request attributes are handled in
RequestPredicates. Previously, the AND/OR/NOT predicates copied all
attributes in a map, and restored that when the delegate predicate(s)
failed.
Now, we only set the attributes when all delegates have succeeded.
Closes gh-30028
This commit ensures that both `ObservationRegsitry` and
`ServerRequestObservationConvention` beans are automatically detected in
the application context if they are unique. This aligns with the
existing behavior for all other builder methods.
Closes gh-31205
AnnotationBeanNameGenerator was written before the introduction of the
MergedAnnotations API and therefore heavily relies on the
AnnotationMetadata abstraction and various helper methods for ASM
compatibility.
However, recent work on determineBeanNameFromAnnotation() has made it
apparent that we should use the MergedAnnotations API directly in
AnnotationBeanNameGenerator where feasible in order to avoid
unnecessary, repeated iterations/streams over the same annotation
metadata.
Closes gh-31203
This commit allows a custom code fragment to provide the code to
create a bean without relying on ConstructorResolver. This is especially
important for use cases that derive from the default behaviour and
provide an instance supplier with the regular runtime scenario.
This is a breaking change for code fragments providing a custom
implementation of the related methods. As it turns out, almost all of
them did not need the Executable argument. Configuration class parsing
is the exception, where it needs to provide a different constructor in
the case of the proxy. To make this use case possible,
InstanceSupplierCodeGenerator has been made public.
Closes gh-31117
This commit replaces the initial allocation size for the content caching
buffer by a `FastByteArrayOutputStream`. With this variant, allocations
are cheap and we don't need to apply heuristics anymore to guess the
best initial buffer size.
See gh-29775
Prior to this commit, the initial buffer size for content caching
allocated in `ContentCachingRequestWrapper` would be:
* the request content length, if available in request headers
* the cache limit size as configured on the wrapper
The latter is really an upper bound and should not be considered as a
good default in most cases. This commit ensures that the request content
length is still used if available, but uses a default 1024 size if it's
not.
While this change will probably cause more reallocations as the buffer
grows, this will avoid large allocations in many cases and should
overall help with GC.
Closes gh-29775
Prior to this commit, @BeforeTransaction and @AfterTransaction
methods could not accept any arguments. This is acceptable with testing
frameworks such as JUnit 4 and TestNG that do not provide support for
parameter injection. However, users of JUnit Jupiter have become
accustomed to being able to accept arguments in lifecycle methods
annotated with JUnit's @BeforeEach, @AfterEach, etc.
As a follow up to the previous commit (see gh-31199), this commit
introduces first-class support for parameter injection in
@BeforeTransaction and @AfterTransaction methods, as demonstrated in
the following example.
@BeforeTransaction
void verifyInitialDatabaseState(@Autowired DataSource dataSource) {
// Use the DataSource to verify the initial DB state
}
Closes gh-30736
In order to be able to support parameter injection in
@BeforeTransaction and @AfterTransaction methods (see gh-30736), this
commit introduces a MethodInvoker API for TestExecutionListeners as a
generic mechanism for delegating to the underlying testing framework to
invoke methods.
The default implementation simply invokes the method without arguments,
which allows TestExecutionListeners using this mechanism to operate
correctly when the underlying testing framework is JUnit 4, TestNG, etc.
A JUnit Jupiter specific implementation is registered in the
SpringExtension which delegates to the
ExtensionContext.getExecutableInvoker() mechanism introduced in JUnit
Jupiter 5.9. This allows a TestExecutionListener to transparently
benefit from registered ParameterResolvers in JUnit Jupiter (including
the SpringExtension) when invoking user methods, effectively providing
support for parameter injection for arbitrary methods.
Closes gh-31199
Prior to this commit, when using RowCallbackHandler or ResultSetExtractor in JdbcClient
and passing a parameter to paramSource(), an exception was thrown stating "No value
supplied for the SQL parameter 'xxxxxx'" because the SqlParameterSource used internally
was the wrong one.
Closes gh-31195
Prior to this commit, `DispatcherServlet` would completely reset the
response (status, headers and body) before handling errors within Spring
MVC. This can cause unintended consequences when Servlet Filters added
response headers before the error happened. Such response headers might
be still required in case of error handling.
This commit changes the complete reset of the response to only resetting
the response buffer, if possible.
Closes gh-31154
See gh-31104
When a handler method is annotated with `@ResponseStatus(reason="...")`,
Spring MVC will use `HttpServletResponse#sendError` to complete the
response. As a result, the Servlet container will send an HTML error
page and any existing data in the response buffer will be cleared.
This commit clarifies the `@ResponseStatus` Javadoc and ensures that a
message is logged at the WARN level if a handler method is annotated
like this and still returns a non-Void value. In this case, the return
value will be ignored and developers should be aware of this fact.
See gh-31113
Closes gh-31121
With this commit, ReactorClientHttpConnector now implements
SmartLifecycle which optionally allows recreating the HttpClient
after ReactorResourceFactory has been updated.
Closes gh-31180
With this commit, ReactorResourceFactory now implements
Lifecycle which allows supporting JVM Checkpoint Restore
in Spring Boot with Reactor Netty server, and helps
to support Reactor Netty client as well.
Closes gh-31178
Prior to this commit, the withoutTableColumnMetaDataAccess() and
includeSynonymsForTableColumnMetaData() methods in SimpleJdbcInsert
incorrectly declared a SimpleJdbcInsertOperations return type, which
prevented method chaining when the instance was declared to be of type
SimpleJdbcInsert.
This commit changes the return types of those methods to
SimpleJdbcInsert to benefit from covariant return types like the rest
of the configuration methods in SimpleJdbcInsert.
Closes gh-31177
Prior to this commit and the previous commit, SimpleJdbcInsert did not
provide built-in support for "quoted identifiers". Consequently, if any
column names conflicted with keywords or functions from the underlying
database, you had to manually quote the column names when specifying
them via `usingColumns(...)`, and there was unfortunately no way to
quote schema and table names.
The previous commit provided rudimentary support for quoted SQL
identifiers (schema, table, and column names) by querying
java.sql.DatabaseMetaData.getIdentifierQuoteString() to determine the
quote string. It also introduced `usingEscaping(boolean)` in
`SimpleJdbcInsertOperations` to enable the feature. However, it
incorrectly quoted the schema and table names together, and it did not
take into account the fact that a quoted identifier should respect the
casing (uppercase vs. lowercase) of the underlying database's metadata.
This commit revises quoted identifier support in `SimpleJdbcInsert` by:
- renaming `usingEscaping(boolean)` to `usingQuotedIdentifiers()`
- quoting schema and table names separately
- respecting the casing (uppercase vs. lowercase) of the underlying
database's metadata when quoting identifiers
- introducing integration tests against an in-memory H2 database
See gh-13874
Closes gh-24013
Prior to this commit, the `RestTemplateAdapter` would manually expand
templated URIs. This means that the `RestTemplate` instance itself would
never see the templated URIs and could not record it in the client
observations at runtime.
This commit ensures that when URI templates are available, the adapter
uses the correct `exchange` method variant.
Fixes gh-31144
As a workaround before a proper solution the Spring team is trying to
find with the Hibernate team in a future version of Hibernate, this
commit introduces 2 GraalVM substitutions that should allow to remove
ByteBuddy reachability with Hibernate 6.3.
Closes gh-29549
BlockingExecutionConfigurer#setExecutor takes an AsyncTaskExecutor
not an Executor as the documentation states. With this commit,
this has been corrected.
Closes gh-31150
This is a follow-up change related to gh-31104.
This change reverts the changes previously made in
`ExceptionHandlerExceptionResolver` and instead attempts to reset the
response directly in `DispatcherServlet` in order to cover all types or
exception handling.
Unlike the previous change, we decided to continue even if the response
was already committed: exception handlers will have a chance to be
called, even if it means they'll have to operate on a garbled response.
This change will cause less disruption, in case existing exception
handlers were relying on this behavior.
See gh-31104
Prior to this commit, the Spring Framework build would publish several
zip artifacts:
* a "*-schema.zip" containing all the XSD schemas produced
* a "*-docs.zip" containing the API docs
* a "*-dist.zip" containing all of the above, plus module jars
Since the reference docs are now produced by Antora in a separate
process, the "*-docs.zip" does not contain the reference docs anymore.
But it still contains the API docs which are automatically fetched from
the artifact repository and published on the docs.spring.io website.
This commit intends to update the current arrangement and optimize the
build.
First, the "*-dist.zip" is not published anymore, since it cannot be
consumed anyway by the community: repo.spring.io does not distribute
release artifacts publicly, developers are expected to get them from
Maven Central. This arrangement is quite dated anyway and is not really
useful in current application build setups.
The generation of API docs is moved to a new "framework-api" module,
separating it from the reference docs module ("framework-docs") which
contains Java, Kotlin and Asciidoctor sources. This removes the custom
javadoc aggregation task and instead uses a dedicated Gradle plugin.
This change also adds a new `-PskipDocs` Gradle project property that
skips entirely the documentation tasks (javadoc, kdocs) as well as the
"distrbution" tasks managed in the framework-api module.
This allows developers to publish locally a SNAPSHOT of Spring Framework
without creating the entire documentation distribution. This is
particularly useful for local testing.
For example, `$ ./gradlew pTML -PskipDocs`.
Closes gh-31049
Prior to this commit, the `ExceptionHandlerExceptionResolver` would
resolve exceptions and handle them by writing to the HTTP response body,
even if the request was already partially handled and content was
written to the response body.
This could result in HTTP responses with some content for the intended
application response, then other content for the handled exception.
This would happen especially when the error would be raised while
writing to the response (for example when serializing content).
This commit attempts to reset the HTTP response before handling the
exception. This effectively resets the response buffer for the body as
well as response headers. If the response is already committed, the
Servlet container raises an exception and the exception handling is
skipped altogether in order to avoid garbled responses.
Closes gh-31104
Prior to this commit, `@Async` and `@EventListener` annotated methods
would lose the the logging and observation contexts whenever their
execution was scheduled on a different Thread.
The Context Propagation library supports this use case and can propagate
context values in ThreadLocals, Reactor Context and more.
This commit introduces a new `TaskDecorator` implementation that
leverages the Context Propagation library. When configured on a
`TaskExecutor`, this allows to properly propagate context value through
the execution of the task.
This implementation is completely optional and requires the
"io.micrometer:context-propagation" library on the classpath. Enabling
this feature must be done consciously and sometimes selectively, as
context propagation introduces some overhead.
Closes gh-31130
When use of the deprecated feature is detected, a WARNING log message
will be generated analogous to the following.
WARN o.s.c.a.AnnotationBeanNameGenerator - Support for convention-based
stereotype names is deprecated and will be removed in a future version
of the framework. Please annotate the 'value' attribute in
@org.springframework.context.annotation.AnnotationBeanNameGeneratorTests$ConventionBasedComponent1
with @AliasFor(annotation=Component.class) to declare an explicit alias
for @Component's 'value' attribute.
See gh-31089
Closes gh-31093
This commit schedules blocking I/O operations on the bounded elastic
scheduler, which includes retrieving the content length and writing
the resource (region).
Closes gh-30928
This commit builds on the recently added support for using @AliasFor to
override the `value` attribute in `@Component, and allows a custom
component name to be specified in both @ControllerAdvice and
@RestControllerAdvice via new `name` attributes.
See gh-31089
Closes gh-21108
Although gh-20615 introduced the use of @AliasFor for @Component(value) in the built-in
stereotype annotations (@Service, @Controller, @Repository, @Configuration, and
@RestController), prior to this commit the framework did not actually rely on @AliasFor
support when looking up a component name via stereotype annotations. Rather, the
framework had custom annotation parsing logic in
AnnotationBeanNameGenerator#determineBeanNameFromAnnotation() which effectively ignored
explicit annotation attribute overrides configured via @AliasFor.
This commit revises AnnotationBeanNameGenerator#determineBeanNameFromAnnotation() so that
it first looks up @Component stereotype names using @AliasFor semantics before falling
back to the "convention-based" component name lookup strategy.
Consequently, the name of the annotation attribute that is used to specify the bean name
is no longer required to be `value`, and custom stereotype annotations can now declare an
attribute with a different name (such as `name`) and annotate that attribute with
`@AliasFor(annotation = Component.class, attribute = "value")`.
Closes gh-31089
Create LinkedHashSet with a initialCapacity, prevent under the hood
table resize cost in continuous add operations. Reduce bootstrap time
in the case of large properties.
See gh-27236
This commit reinstates support for the legacy JSR-250
@javax.annotation.ManagedBean and JSR-330 @javax.inject.Named
annotations with regard to component name lookups and component
scanning.
Closes gh-31090
If you wish to stop after a certain number of attempts with an
`ExponentialBackOff` you have to calculate the `maxElapsedTime`
corresponding to the number of attempts.
Add a new property to make it more convenient to stop after a
certain number of attempts.
See gh-27071
Optimize TransactionSynchronizationManager.getSynchronizations() to
avoid sorting and ArrayList creation in case of a single
TransactionSynchronization.
See gh-27335
This commit instruments the new `RestClient` HTTP client for
observability. Since this client is sharing its HTTP infrastructure with
`RestTemplate` and operates on the same request/response types, this
instrumentation reuses the Observation convention and context.
This choice makes sense since one can build a new `RestClient` instance
using a `RestTemplate` instance, effectively reusing the underlying
configuration.
Closes gh-31114
This commit adds support for Kotlin Coroutines to Spring AOP
by leveraging CoroutinesUtils#invokeSuspendingFunction in
AopUtils#invokeJoinpointUsingReflection to convert it to the
equivalent Publisher return value, like in other parts of Spring
Framework.
That allows method interceptors with Reactive support to process
related return values.
CglibAopProxy#processReturnType and JdkDynamicAopProxy#invoke
take care of the conversion from the Publisher return value
to Kotlin Coroutines.
Reactive transactional and HTTP service interface support
have been refined to leverage those new generic capabilities.
Closes gh-22462
This commit implements StringToRegexConverter in Java
in order to avoid circular dependencies between Java
and Kotlin codes that can break IDE support, and for
consistency with the rest of the codebase.
See gh-24311
This commits adds a getContentAsString method to
ContentCachingRequestWrapper that uses the configured charset without
copying the underlying byte array.
See gh-30709
Since an annotation cannot be extended in Java, there is no need to use
the INHERITED_ANNOTATIONS SearchStrategy to search for meta-annotations
on an annotation.
Prior to this commit, there was an issue with the semantics of property
source overrides. Specifically, a @PropertySource annotation present as
a meta-annotation on a @Configuration class was registered with higher
precedence than a @PropertySource annotation declared closer to (or
directly on) the @Configuration class. Consequently, there was no way
for a "local" @PropertySource annotation to override properties
registered via @PropertySource as a meta-annotation.
This commit addresses this issue by introducing a new overloaded
getMergedRepeatableAnnotationAttributes() variant in
AnnotatedTypeMetadata that allows the caller to supply a
sortByReversedMetaDistance flag. When set to `true`, the annotation
search results will be sorted in reversed order based on each
annotation's meta distance, which effectively orders meta-annotations
before annotations that are declared directly on the underlying element.
ConfigurationClassParser and AnnotationConfigUtils have been updated to
use this new repeatable annotation search method for @PropertySource.
Closes gh-31074
Inspired by the recently added support for resource patterns in
@PropertySource locations, this commit adds the same support for
resource locations in @TestPropertySource.
For example, assuming the `config` folder in the classpath contains
only 3 files matching the pattern `file?.properties`,
... the following:
@TestPropertySource("classpath:/config/file1.properties")
@TestPropertySource("classpath:/config/file2.properties")
@TestPropertySource("classpath:/config/file3.properties")
... or:
@TestPropertySource({
"classpath:/config/file1.properties",
"classpath:/config/file2.properties",
"classpath:/config/file3.properties"
})
... can now be replaced by:
@TestPropertySource("classpath*:/config/file?.properties")
See gh-21325
Closes gh-31055
Includes a revision of BeanProperty/DataClassRowMapper with exclusively constructor-based configuration and without JDBC-inherited legacy settings.
Closes gh-27282
Closes gh-26021
Prior to this commit, inlined properties could only be supplied as an
array of Strings as follows.
@TestPropertySource(properties = {
"key1 = value1",
"key2 = value2"
})
Although a user could supply a text block, it was previously rejected
due to a "single key-value pair per string" check in
TestPropertySourceUtils.convertInlinedPropertiesToMap(String...).
This commit removes that restriction and allows the above example to be
refactored to use a text block as follows.
@TestPropertySource(properties = """
key1 = value1
key2 = value2
"""
)
Closes gh-31053
This commit moves ServerWebExchange Kotlin extensions
where they belong: in the spring-web module with the
org.springframework.web.server package, like
ServerWebExchange itself.
The extensions in the wrong location are deprecated
and semi-automated migration to the new variants is
made possible via @Deprecated + ReplaceWith(...).
Some tests have been added as well.
Closes gh-31046
Includes query(Class) method with value and property mapping support on JdbcClient.
JdbcClient's singleColumn/singleValue are declared without a Class parameter now.
Closes gh-26594
See gh-30931
This commit ensures that the Observability instrumentation for
`@JmsListener` does not assume that micrometer-core is on the classpath
and guards against direct usage.
Closes gh-30335
This commit adds observability support for Jakarta JMS support in
spring-jms support. This feature leverages the `JmsInstrumentation`
infrastructure in `io.micrometer:micrometer-core` library.
This instruments the `JmsTemplate` and the `@JmsListener` support to
record observations:
* "jms.message.publish" when the `JmsTemplate` sends a message
* "jms.message.process" when a message is processed by a `@JmsListener`
annotated method
The observation `Convention` and `Context` implementations are shipped
with "micrometer-core".
Closes gh-30335
Prior to this commit, Spring failed to find multiple composed
@ComponentScan and @PropertySource annotations or multiple
@ComponentScans and @PropertySources container annotations. The reason
was due to lacking support in the AnnotatedTypeMetadata API.
This commit introduces support for finding all @ComponentScan and
@PropertySource annotations by making use of the new
getMergedRepeatableAnnotationAttributes() method in
AnnotatedTypeMetadata.
Closes gh-30941
See gh-31041
AnnotatedTypeMetadata has various methods for finding annotations;
however, prior to this commit it did not provide explicit support for
repeatable annotations.
Although it is possible to craft a search "query" for repeatable
annotations using the MergedAnnotations API via getAnnotations(), that
requires intimate knowledge of the MergedAnnotations API as well as the
structure of repeatable annotations.
Furthermore, the bugs reported in gh-30941 result from the fact that
AnnotationConfigUtils attempts to use the existing functionality in
AnnotatedTypeMetadata to find repeatable annotations without success.
This commit introduces a getMergedRepeatableAnnotationAttributes()
method in AnnotatedTypeMetadata that provides dedicated support for
finding merged repeatable annotation attributes with full @AliasFor
semantics.
Closes gh-31041
The Javadoc for getAnnotationAttributes() states that it supports
"attribute overrides on composed annotations"; however, it actually
supports @AliasFor in general, including attribute aliases within a
given annotation.
This commit updates the Javadoc and corresponding tests to reflect that.
Closes gh-31042
This commit adds support for inlined Kotlin value
class properties in SpEL by leveraging Kotlin
reflection instead of Java reflection broken
by the mangled method name.
Closes gh-30468
This commit adds support for Kotlin value classes annotated
with @JvmInline to BeanUtils#findPrimaryConstructor.
This is only the first step, more refinements are expected
to be needed to achieve a comprehensive support of Kotlin
values classes in Spring Framework.
Closes gh-28638
This commit makes the recently introduced
addPropertySourcesToEnvironment(ConfigurableEnvironment, ResourceLoader,
List<PropertySourceDescriptor>) method in TestPropertySourceUtils public
so that it can be used by third parties (for example, Spring Boot).
Closes gh-30981
Java 12 introduced java.lang.Class#componentType() as a shortcut for
getComponentType().
Since we started using arrayType() in fe5560400c, this commit switches
to componentType() for consistent API usage style.
Includes ConfigurableTransactionManager interface for listener registration.
Includes additional introspection methods on TransactionExecution interface.
Includes default method declarations on TransactionStatus/SmartTransactionObject.
Closes gh-27479
Prior to this commit, property files configured (or inferred) via
@TestPropertySource were read using the default encoding of the JVM.
This commit introduces an `encoding` attribute in @TestPropertySource
which allows developers to specify an explicit encoding for test
property files.
Closes gh-30982
This commit changes the `synchronized` usage into a `ReentrantLock`, in
order to guard write operations with a construct that does not pin
virtual threads to the current platform thread on JDK21.
Closes gh-30996
Spring Framework 4.3 introduced the `PropertySourceFactory` SPI for use
with `@PropertySource` on `@Configuration` classes; however, prior to
this commit there was no mechanism to support custom properties file
formats in `@TestPropertySource` for integration tests.
This commit introduces support for configuring a custom
`PropertySourceFactory` via a new `factory` attribute in
`@TestPropertySource` in order to support custom file formats such as
JSON, YAML, etc.
For example, if you create a YamlPropertySourceFactory, you can use it
in integration tests as follows.
@SpringJUnitConfig
@TestPropertySource(locations = "/test.yaml", factory = YamlPropertySourceFactory.class)
class MyTestClass { /* ... /* }
If a custom factory is not specified, traditional `*.properties` and
`*.xml` based `java.util.Properties` file formats are supported, which
was the existing behavior.
Closes gh-30981
This commit allows to configure custom file
extensions in ReloadableResourceBundleMessageSource
thanks to a new setFileExtensions setter.
Combined with setPropertiesPersister, it allows
custom implementations supporting any kind of
property file.
Closes gh-18990
Prior to this commit, if an error was encountered during build-time AOT
processing, the error was logged at WARN/DEBUG level, and processing
continued.
With this commit, test AOT processing now fails on error by default. In
addition, the `failOnError` mode can be disabled by setting the
`spring.test.aot.processing.failOnError` Spring/System property to
`false`.
Closes gh-30977
TransactionalApplicationListener and TransactionalEventListener automatically detect a reactive TransactionContext as the event source and register the synchronization accordingly. TransactionalEventPublisher is a convenient delegate for publishing corresponding events with the current TransactionContext as event source. This can also serve as a guideline for similar reactive event purposes.
Closes gh-27515
Closes gh-21025
Closes gh-30244
Prior to this commit, MappedInterceptor had a getPathPatterns() method
that returned the include patterns.
This commit introduces getIncludePathPatterns() (which effectively
replaces getPathPatterns()) and getExcludePathPatterns(). In addition,
this commit deprecates getPathPatterns().
Closes gh-30971
Where possible, switch to the Long.parseLong variant that accepts a
start and end index for the supplied CharSequence, thus avoiding making
unnecessary copies of the String input.
Closes gh-30710
Delegates to JdbcTemplate/NamedParameterJdbcTemplate underneath the covers.
Supports parameter objects/records through SimplePropertySqlParameterSource.
Closes gh-30931
Includes CompletableFuture-based retrieve operations on Spring's Cache interface.
Includes support for retrieve operations on CaffeineCache and ConcurrentMapCache.
Includes async cache mode option on CaffeineCacheManager.
Closes gh-17559
Closes gh-17920
Closes gh-30122
Includes failOnError method on Errors interface for use with validateObject.
Declares many Errors methods as default methods for lean SimpleErrors class.
Closes gh-19877
Prior to this commit a @CachePut operation would fail if the key
expression is invalid, but guarded with an unless condition as the
former was evaluated too early. This commit makes sure that key for
a put is only evaluated if the put operation is active.
Note that this does not apply for @Cacheable as the key needs to be
computed early to determine if a matching entry exists in the cache.
See gh-22769
This commit changes the default request factory from the
SimpleClientHttpRequestFactory to the JdkClientHttpRequestFactory if
available. It also adds detection logic for OkHttp and Jetty.
AbstractTransactionManagementConfiguration.transactionalEventListenerFactory() creating a RestrictedTransactionalEventListenerFactory now.
See gh-30679
Previously, BeanInstanceSupplier had three variants of the
`withGenerator` callback, one with a bi function, one with a function,
and with a supplier. This could lead to compilation failure when the
target type has a method with the same name and a number of arguments
that match another variant.
It turns out the supplier-based variant is only used a shortcut. This
commit deprecates it and update ghe code generation to use the function
instead.
Closes gh-29278
The method includes logic that is currently in
ViewResolutionResultHandler but fits well in BindingContext and also
includes the call to saveModel method from the InitBinderBindingContext
subclass, which was called too early until now from
RequestMappingHandlerAdapter before the model has been fully updated.
This mirrors a similar method in ModelFactory on the Spring MVC side
which also combines those two tasks.
Closes gh-30821
Now that HttpClientAdapter is deprecated and replaced by HttpExchangeAdapter
and ReactorHttpExchangeAdapter, our tests should use the new contracts.
See gh-30117
Previously, the runtimeHintsTest task configuration made a cross
project task reference to obtain the jar path of spring-core-test
to use in the -javaagent argument.
With this change, a dedicated configuration exists to resolve the
project artifact without the need to reference the jar task of
spring-core-test.
Closes gh-30838
Previously, an afterEvaluate call was used to read the values of the
runtimeHintsAgent extension and the -javaagent parameter supplied to
the runtimeHintsTest task was evaluated eagerly.
With this change the construction of the -javaagent parameter is
deferred until task execution and the extension properties are
evaluated lazily.
See gh-30838
Prior to this change, a build cache miss would occur in
runtimeHintsTest tasks when executing the build from two different
locations, causing the tasks to re-execute. This was due to an
absolute path to the agent jar being included in the -javaagent
argument supplied to the test JVM process.
This change introduces a RuntimeHintsAgentArgumentProvider allowing
finer grained control over the way Gradle computes the build cache
key. With this change, the contents of the agent jar file are
considered, rather than the absolute file location.
See gh-30838
ResolvableTypes are only considered equal if of the very same class now.
As a consequence, a forRawClass result is not equal to forClass anymore.
The new equalsType method is available for plain type equality checks.
Closes gh-28608
Closes gh-27748
This commit introduces an overloaded version of RestClient::exchange,
adding a boolean parameter that indicates whether the connection is
closed after the exchange function is executed.
See gh-29552
This commit creates a placeholder for future RestClient reference
documentation. It also creats a link to RestClient from the RestTemplate
javadoc.
See gh-30826
This commit moves HttpHeaders that are used in multiple places (client
and server, reactive and non-reactive) to a new, separate http.support
package.
Closes gh-30823
This commit ensures that ServerResponse.HeadersBuilder::build can throw
an exception, by introducing a separate functional interface that does
allow for exceptions to be thrown.
Closes gh-30818
As a consequence, the spring-messaging HandlerMethod detects interface parameter annotations as well, and the same is available for other HandlerMethod variants.
Closes gh-30801
This commit introduces the RestClient, a synchronous HTTP client that
offers an API similar to WebClient, using the same infrastructure (i.e.
request factory, error handler, interceptors, etc) as RestTemplate.
Closes gh-29552
Extract the default logic for resolving the name of an @Valid
parameter into an ObjectNameResolver, and use it when there isn't
one configured.
See gh-30644
To handle method validation errors in ResponseEntityExceptionHandler,
MethodValidationException and associated types should not depend on
Bean Validation. To that effect:
1. MethodValidationResult and ParameterValidationResult no longer make
the underlying ConstraintViolation set available, and instead expose
only the adapted validation errors (MessageSourceResolvable, Errors),
analogous to what SpringValidatorAdapter does. And likewise
MethodValidationException no longer extends ConstraintViolationException.
2. MethodValidationPostProcessor has a new property
adaptConstraintViolations to decide whether to simply raise
ConstraintViolationException, or otherwise to adapt the ConstraintViolations
and raise MethodValidationException instead, with the former is the default
for compatibility.
3. As a result, the MethodValidator contract can now expose methods that
return MethodValidationResult, which provided more flexibility for handling,
and it allows MethodValidationAdapter to implement MethodValidator directly.
4. Update Javadoc in method validation classes to reflect this shift, and
use terminology consistent with Spring validation in classes without an
explicit dependency on Bean Validation.
See gh-30644
- Update method order
- Do not automatically create MessageSource arguments in
WebExchangeBindException constructor as they're more likely to be
created via getDetailMessageArguments with MessageSource passed in.
See gh-30644
Remove throwIfViolationsPresent and replace with static factory
methods on MethodValidationException taking MethodValidationResult,
which makes handling more explicit and allows choice of what
exception to raise.
Update MethodValidationResult to expose the target, the method, and
forReturnValue flag, so the code handling an exception will have
access to all details.
See gh-30644
By default, the JDK HttpClient's HttpRequest does not allow Connection,
Content-Length, Expect, Host, or Upgrade headers to be set, but this can
be overriden with the `jdk.httpclient.allowRestrictedHeaders` system
property.
See https://bugs.openjdk.org/browse/JDK-8213696
Closes gh-30787
This commit adds support for WildcardType bounds resolution,
commonly seen in Kotlin due to declaration-site variance,
but also possible in Java even if less common.
Closes gh-22313
- Removed duplicate Client in types names.
- Removed buffering in favor of OutputStream to
Flow.Publisher<ByteBuffer> bridge.
- Made request and types package private.
- Various other small improvements.
Closes gh-30478
This commit updates the `ScheduledTaskObservationDocumentation` to
better align the contributed KeyValues with OpenTelemetry conventions
for observations of code executions.
Instead of a "target.type" key with the bean class simple name, this
is now contributing the canonical class name of the bean under the
"code.namespace" key.
The "method.name" key is renamed to "code.function" and its values
remain unchanged.
Closes gh-30721
This commit adds support for Kotlin parameter default values
in handler methods. It allows to write:
@RequestParam value: String = "default"
as an alternative to:
@RequestParam(defaultValue = "default") value: String
Both Spring MVC and WebFlux are supported, including on
suspending functions.
Closes gh-21139
This commit introduces a Kotlin-specific implementation
of the ExchangeFilterFunction interface that allows for
using coroutines, similar to what CoWebFilter does on
server-side.
Closes gh-30650
This commit enhances the `ScheduledAnnotationBeanPostProcessor` to
instrument `@Scheduled` methods declared on beans. This will create
`"tasks.scheduled.execution"` observations for each execution of a
scheduled method. This supports both blocking and reactive variants.
By default, observations are no-ops; developers must configure the
current `ObservationRegistry` on the `ScheduledTaskRegistrar` by using a
`SchedulingConfigurer`.
Closes gh-29883
This commit changes the Java system property used to
control PreComputeFieldFeature verbose logging from
spring.aot.precompute to spring.native.precompute.log
in order to clarify its purpose and avoid confusion
with AOT processing of JVM bytecode or Java sources.
See gh-30571
This allows re-use of existing MethodParameter instances from controller
methods with cached metadata, and also ensures additional capabilities
such as looking up parameter annotations on interfaces.
See gh-29825
1. Remove list markers (those can be provided in message).
2. Use ", and " between errors for readability.
3. Remove single quotes around errors.
4. If MessageSource is provided, use resolved message as is since in
that case applications have full control over each message.
Closes gh-30198
This commit changes the order of RouterFunctionMapping defined
in WebMvcConfigurationSupport from 3 to -1 in order to achieve
better consistency between WebMVC and WebFlux. It also reduces
the surprise factor. That way, functional routes are always
before annotation-based ones.
Closes gh-30278
This commit makes sure that profiles that have been explicitly enabled
during AOT optimizations are automatically enabled when using those
optimizations.
If other profiles are set at runtime, they take precedence over the ones
defined during AOT processing.
Closes gh-30421
In the previous commit which introduced the new context failure threshold
support in the TestContext framework, the context failure tracking was
tied to an instance of DefaultCacheAwareContextLoaderDelegate.
Consequently, the feature was only supported within a given test class.
This commit therefore moves context failure tracking to the ContextCache
SPI (and DefaultContextCache) so that the feature applies to all test
classes within the current test suite (i.e., JVM).
This commit also includes the total failure count in the statistics
logged by the DefaultContextCache.
See gh-14182
This set of commits introduces ApplicationContext "failure threshold"
support in the Spring TestContext Framework (TCF).
Specifically, this new feature avoids repeated attempts to load a
failing ApplicationContext in the TCF, based on a failure threshold
which defaults to 1 but can be configured via a system property.
See individual commits for details.
Closes gh-14182
This commit makes the failure threshold value configurable via a JVM
system property or Spring property named
"spring.test.context.failure.threshold".
See gh-14182
This commit introduces initial support for a new "context failure
threshold" feature in the Spring TestContext Framework (TCF).
Specifically, DefaultCacheAwareContextLoaderDelegate now tracks how
many times a failure occurs when attempting to load an
ApplicationContext and preemptively throws an IllegalStateException for
subsequent attempts to load the same context if the configured failure
threshold has been exceeded.
See gh-14182
Related to gh-30052, we should improve ParameterNameDiscoverer
Kotlin tests to make sure DefaultParameterNameDiscoverer behaves
as expected and is consistent with
KotlinReflectionParameterNameDiscoverer behavior.
Closes gh-30618
Prior to this commit, only the letters 'A' - 'Z' (ignoring case) were
supported in identifiers (i.e., property, field, and variable names).
This known (yet undocumented) limitation prevented the use of characters
such as 'ü', 'ñ', 'é' as well as letters from other character sets such
as Chinese, Japanese, Cyrillic, etc.
This commit lifts that restriction by delegating to Character.isLetter()
to determine if a character in a SpEL expression is a letter.
Closes gh-30580
This commit adds a note in the reference documentation stating that
`ErrorHandler` infrastructure is not involved when reactive methods send
an error signal: the exception is sent as a message in the pipeline and
is not thrown from the task `Runnable`.
See gh-23533
This commit adds support for `@Scheduled` annotation on reactive
methods and Kotlin suspending functions.
Reactive methods are methods that return a `Publisher` or a subclass
of `Publisher`. The `ReactiveAdapterRegistry` is used to support many
implementations, such as `Flux`, `Mono`, `Flow`, `Single`, etc.
Methods should not take any argument and published values will be
ignored, as they are already with synchronous support.
This is implemented in `ScheduledAnnotationReactiveSupport`, which
"converts" Publishers to `Runnable`. This strategy keeps track of
active Subscriptions in the `ScheduledAnnotationBeanPostProcessor`,
in order to cancel them all in case of shutdown.
The existing scheduling support for tasks is reused, aligning the
triggering behavior with the existing support: cron, fixedDelay and
fixedRate are all supported strategies.
If the `Publisher` errors, the exception is logged at warn level and
otherwise ignored. As a result new `Runnable` instances will be
created for each execution and scheduling will continue.
The only difference with synchronous support is that error signals
will not be thrown by those `Runnable` tasks and will not be made
available to the `org.springframework.util.ErrorHandler` contract.
This is due to the asynchronous and lazy nature of Publishers.
Closes gh-23533
Closes gh-28515
This commit disables support for evaluating SpEL expressions from
untrusted sources by default. Specifically, this applies to the
SpEL-based 'selector' header support in WebSocket messaging, which
includes the DefaultSubscriptionRegistry and the classes used to
configure the 'selector' header name (SimpleBrokerMessageHandler and
SimpleBrokerRegistration).
The selector header support remains in place but will have to be
explicitly enabled beginning with Spring Framework 6.1.
For example, a custom implementation of WebSocketMessageBrokerConfigurer
can override the configureMessageBroker() method and configure the
selector header name as follows.
registry.enableSimpleBroker().setSelectorHeaderName("selector");
Closes gh-30550
This commit ensures that ClientHttpRequest implementations implement
StreamingHttpOutputMessage, so that they do not expose an OutputStream,
but store a handle capable of writing to a stream instead.
Closes gh-30557
This commit polishes the previous change, ensuring that if the request
uses a wildcard subtype with an ndjson suffix then the wildcard isn't
present in the response's Content-Type.
Insteand, in that case we would fall back to `applicatin/x-ndjson` (the
base ndjson media type), assuming that the requester is only interested
in the ndjson nature of the underlying representation and not in the
specific semantics of any subtype.
See commit 9332b3f
See gh-26817
This commit adds support of parsing a simple long from a String and
turning it to an `Instant` by considering it represents a timestamp in
milliseconds (see `Instant.ofEpochMilli`). Failing to parse a long from
the String, the previous algorithm is used: first check for an RFC-1123
representation then an ISO_INSTANT representation.
See gh-30312
Closes gh-30546
This commit ports and adapts spring-jdbc's `BeanPropertyRowMapper` and
`DataClassRowMapper` to spring-r2dbc, allowing to `map` rows or
outParameters to object instances, data classes or records.
See gh-26021
Closes gh-30530
This commit adds `application/*+x-ndjson`, a wildcard media type which
covers all types that can be parsed as nd-json, to the list of media
types the ReactiveTypeHandler considers for a streaming response in
WebMVC.
As a result, a request which for example `Accept` the
`application/vnd.myapp.v1+x-ndjson` media type will generate a response
with the same `Content-Type`, with newline-delimited json objects being
streamed in the response body.
Closes gh-26817
Instead of having antora run always, which happens regardless of
whether anything has changed, we'll have it invoked as part of the CI
build, and we'll have to run it locally ourselves when necessary.
See gh-30481
This commit raises the SnakeYAML baseline version to 2.0.
While most Spring applications are not affected by CVE-2022-1471,
upgrading this version should prevent automated tools from raising this
as a security issue. Such tools usually do not understand that YAML
parsing in Spring is about reading configuration, not parsing untrusted
content.
Closes gh-30048
Prior to this commit, the Observation instrumentation for Reactive
server applications was implemented with a `WebFilter`. This allowed to
record observations and set up a tracing context for the controller
handlers.
The limitation of this approach is that all processing happening at a
lower level is not aware of any observation. Here, the
`HttpWebHandlerAdapter` handles several interesting aspects:
* logging of HTTP requests and responses at the TRACE level
* logging of client disconnect errors
* handling of unresolved errors
With the current instrumentation, these logging statements will miss the
tracing context information. As a result, this commit deprecates the
`ServerHttpObservationFilter` in favor of a more direct instrumentation
of the `HttpWebHandlerAdapter`. This enables a more precise
instrumentattion and allows to set up the current observation earlier in
the reactor context: log statements will now contain the relevant
information.
Fixes gh-30013
Prior to this commit, the SpringExtension looked up the
TestInstance.Lifecycle and ExecutionMode using
TestContextAnnotationUtils; however, using TestContextAnnotationUtils is
problematic since the TestInstance.Lifecycle and ExecutionMode can be
configured globally via configuration parameters instead of locally via
the @TestInstance and @Execution annotations.
This commit addresses these issues by looking up the
TestInstance.Lifecycle and ExecutionMode via JUnit Jupiter's
ExtensionContext which takes into account both global and local
configuration.
See gh-30020
This commit updates the script that builds PRs to add locations to the
installed JDK within the CI image. Without this change, PRs fail to
build because of the recently introduced JDK21 toolchain requirement in
the Spring Framework build.
Closes gh-30472
This commit:
- Refine the wording used in logs and Javadoc
- Avoid calling awaitPreventShutdownBarrier() in afterRestore()
- Add logs to print the restart duration
See gh-29921
Prior to this commit, some FreeMarker tests would fail when involving
property lookup in a template file, where this bean property is linked
with a method implemented as a default method on an interface.
While I did not manage to reproduce this behavior in an independent test
case, this is most likely related to a change in JDK 21:
https://bugs.openjdk.org/browse/JDK-8071693
This commit changes the template expression to using the default method
directly.
This commit makes sure that the SimpleAsyncTaskExecutor only creates a
virtual thread when the virtualThreadDelegate is set, and not an
additional kernel thread as well.
See gh-30241
VirtualThreadDelegate built on JDK 21 for multi-release jar.
Includes dedicated VirtualThreadTaskExecutor as lean option.
Includes setVirtualThreads flag on SimpleAsyncTaskExecutor.
Includes additional default methods on AsyncTaskExecutor.
Closes gh-30241
This commit modifies the way the `@RecordApplicationEvents` annotation
works in tests, allowing for capture of events from threads other than
the main test thread (async events) and for the assertion of captured
event from a separate thread (e.g. when using `Awaitility`).
This is done by switching the `ApplicationEventsHolder` to use an
`InheritedThreadLocal`.
There is a mutual exclusion between support of asynchronous events vs
support of JUnit5 parallel tests with the `@TestInstance(PER_CLASS)`
mode. As a result, we favor the former and now `SpringExtension` will
invalidate a test class that is annotated (or meta-annotated, or
enclosed-annotated) with `@RecordApplicationEvents` AND
`@TestInstance(PER_CLASS)` AND `@Execution(CONCURRENT)`.
See gh-29827
Closes gh-30020
This commit adds support for MethodHandles in SpEL, using the same
syntax as user-defined functions (which also covers reflective Methods).
The most benefit is expected with handles that capture a static method
with no arguments, or with fully bound handles (where all the arguments
have been bound, including a target instance as first bound argument
if necessary). Partially bound MethodHandle should also be supported.
A best effort approach is taken to detect varargs as there is no API
support to determine if an argument is a vararg or an explicit array,
unlike with Method. Argument conversions are also applied. Finally,
array repacking is not always necessary with varargs so it is only
performed when the vararg is the sole argument to the invoked method.
See gh-27099
Closes gh-30045
This commit improves both the javadoc and the reference guide section on
the Elvis SpEL operator to clarify that in addition to `null` objects,
empty Strings also lead the operator to evaluate to its second operand.
The reference guide's advanced snippet is modified to use such an empty
String instead of `null` to make that behavior prominent with some code.
See gh-30318
Closes gh-30352
RuntimeHintsAgentPlugin purpose is to verify that the reflective
invocations expected match the ones performed.
gh-30242 introduces a code path where the reflective invocation
is skipped when running on native.
This issue set the system property "org.graalvm.nativeimage.imagecode"
to "runtime" when running runtime tests with the agent in order to
make sure the code path tested for those tests is the native one.
Closes gh-30422
Prior to this commit, the toString() implementation in ProfilesParser
(which is the internal implementation of Profiles.of()) concatenated
profile expressions with " or ".
For example, the string representation of
Profiles.of("spring & framework", "java | kotlin") was
"spring & framework or java | kotlin".
This commit improves the toString() implementation by wrapping
individual profile expressions in parentheses and concatenating them
with " | ".
For example, the string representation from the previous example is now
"(spring & framework) | (java | kotlin)".
This makes it easier to read (for example, when debugging) and
comprehend.
As an additional benefit, the result of invoking toString() can even be
used as a logically equivalent composite profile expression, though
that is not the primary goal of this change.
Closes gh-30374
This commit enables sub-classes to better customize resource selection
and resource loading in `ReloadableResourceBundleMessageSource`, without
a need to duplicate the caching logic of `refreshProperties`.
See gh-30334
Closes gh-30369
This commit optimizes `DefaultLifecycleProcessor::stopBeans` by using a
`TreeMap` when gathering the `LifecycleGroup`s during stopBeans. It also
switches to a functional style using `computeIfAbsent`.
Finally, it further optimizes `LifecycleGroup` by removing sorting of
`LifecycleGroupMember` members list entirely, turning the class into a
simple record.
This is possible because the members list is already comprised of
members which all share the same phase value, so sorting according to
each member's phase is redundant.
Closes gh-30361
Co-authored-by: Simon Baslé <sbasle@vmware.com>
On windows, the `*` character is not allowed in a directory's name.
When trying to append a glob pattern to a `Path` (`path.resolve("**")`),
if the underlying `Path.getFileSystem()` is windows then an
`InvalidPathException` is thrown.
The NoHttp plugin doesn't really need a `Path` but a glob `String`, so
this commit uses a simple String concatenation in order to append the
wildcard part (with the canonical path separator for good measure).
Closes gh-30355
This commit adds support for the @XmlSeeAlso annotation in the
Jaxb2XmlDecoder. This includes
- Finding the set of possible qualified names given a class name, rather
than a single name.
- Splitting the XMLEvent stream when coming across one of the names in
this set.
Closes gh-30167
- Split Validator::of into two factory methods:
- forInstanceOf using Class::isAssignableFrom
- forType using Class::equals
- Moved anonymous implementation into TypedValidator with default access
Closes gh-30341
This commit introduces `of` method in `Validator` to provide a way to
create a validator for the specific type `<T>` using `BiConsumer<T, Errors>`
and define the validator in a functional way.
This also eliminates the boilerplate for implementing the `supports` method.
This commit removes the `-PmainToolchain` option from our build, since
it was not broadly used. Instead, the language level is now configured
in the `JavaConventions` for JDK 17.
The `-PtestToolchain` option is still available for testing Spring
Framework with other JDKs (i.e., compiling and running tests with a JDK
that's not the baseline).
See gh-30339
This commit moves the checkstyle conventions from the build.gradle
script to a buildSrc convention, ensuring that the same configuration is
applied to all checkstyle tasks.
See gh-30339
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x?groups=Build") [](https://ge.spring.io/scans?search.rootProjectNames=spring)
# <img src="framework-docs/src/docs/spring-framework.png" width="80" height="80"> Spring Framework [](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.1.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".
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring/docs/current/spring-framework-reference/overview.html#spring-introduction) section as reference for a more complete introduction.
Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the [Overview](https://docs.spring.io/spring-framework/reference/overview.html) section of the reference documentation for a more complete introduction.
## Code of Conduct
@@ -14,7 +14,7 @@ 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](framework-docs/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/reference/) and [source](framework-docs/modules/ROOT)), 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
@@ -31,7 +31,7 @@ Information regarding CI builds can be found in the [Spring Framework Concourse
## Stay in Touch
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [news feed](https://spring.io/blog/category/news).
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [releases feed](https://spring.io/blog/category/releases).
| A boolean flag that controls whether errors encountered during AOT processing in the
_Spring TestContext Framework_ should result in an exception that fails the overall process.
See xref:testing/testcontext-framework/aot.adoc[Ahead of Time Support for Tests].
| `spring.test.constructor.autowire.mode`
| The default _test constructor autowire mode_ to use if `@TestConstructor` is not present
on a test class. See xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[Changing the default test constructor autowire mode]
.
on a test class. See xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[Changing the default test constructor autowire mode].
| `spring.test.context.cache.maxSize`
| The maximum size of the context cache in the _Spring TestContext Framework_. See
For this to work, the annotated types must be woven with the AspectJ weaver. You can
either use a build-time Ant or Maven task to do this (see, for example, the
https://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html[AspectJ Development
{aspectj-docs-devguide}/antTasks.html[AspectJ Development
Environment Guide]) or load-time weaving (see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework]). The
`AnnotationBeanConfigurerAspect` itself needs to be configured by Spring (in order to obtain
a reference to the bean factory that is to be used to configure new objects). If you
@@ -399,7 +398,7 @@ The focus of this section is on configuring and using LTW in the specific contex
Spring Framework. This section is not a general introduction to LTW. For full details on
the specifics of LTW and configuring LTW with only AspectJ (with Spring not being
involved at all), see the
https://www.eclipse.org/aspectj/doc/released/devguide/ltw.html[LTW section of the AspectJ
{aspectj-docs-devguide}/ltw.html[LTW section of the AspectJ
Development Environment Guide].
The value that the Spring Framework brings to AspectJ LTW is in enabling much
@@ -421,7 +420,7 @@ who typically are in charge of the deployment configuration, such as the launch
Now that the sales pitch is over, let us first walk through a quick example of AspectJ
LTW that uses Spring, followed by detailed specifics about elements introduced in the
@@ -17,7 +17,7 @@ Applying such optimizations early implies the following restrictions:
* The beans defined in your application cannot change at runtime, meaning:
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related https://github.com/spring-projects/spring-framework/issues/29555[spring-framework#29555] issue).
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).
* Make sure that the bean type is as precise as possible.
TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.
@@ -27,7 +27,7 @@ A Spring AOT processed application typically generates:
* Java source code
* Bytecode (usually for dynamic proxies)
* {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.
* {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] for the use of reflection, resource loading, serialization, and JDK proxies.
NOTE: At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM.
We intend to support more JVM-based use cases in future generations.
@@ -35,7 +35,7 @@ We intend to support more JVM-based use cases in future generations.
[[aot.basics]]
== AOT engine overview
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {api-spring-framework}/aot/generate/GenerationContext.html[`GenerationContext`]:
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:
* Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
@@ -81,7 +81,7 @@ Once this part completes, the `BeanFactory` contains the bean definitions that a
[[aot.bean-factory-initialization-contributions]]
== Bean Factory Initialization AOT Contributions
Components that want to participate in this step can implement the {api-spring-framework}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
Components that want to participate in this step can implement the {spring-framework-api}/beans/factory/aot/BeanFactoryInitializationAotProcessor.html[`BeanFactoryInitializationAotProcessor`] interface.
Each implementation can return an AOT contribution, based on the state of the bean factory.
An AOT contribution is a component that contributes generated code that reproduces a particular behavior.
@@ -156,6 +156,7 @@ Java::
/**
* Bean definitions for {@link DataSourceConfiguration}
*/
@Generated
public class DataSourceConfiguration__BeanDefinitions {
/**
* Get the bean definition for 'dataSourceConfiguration'
@@ -190,6 +191,9 @@ Java::
NOTE: The exact code generated may differ depending on the exact nature of your bean definitions.
TIP: Each generated class is annotated with `org.springframework.aot.generate.Generated` to
identify them if they need to be excluded, for instance by static analysis tools.
The generated code above creates bean definitions equivalent to the `@Configuration` class, but in a direct way and without the use of reflection if at all possible.
There is a bean definition for `dataSourceConfiguration` and one for `dataSourceBean`.
When a `datasource` instance is required, a `BeanInstanceSupplier` is called.
@@ -256,6 +260,13 @@ Java::
If you are registering bean definitions programmatically, consider using `RootBeanBefinition` as it allows to specify a `ResolvableType` that handles generics.
[[aot.bestpractices.constructors]]
=== Avoid Multiple Constructors
The container is able to choose the most appropriate constructor to use based on several candidates.
However, this is not a best practice and flagging the preferred constructor with `@Autowired` if necessary is preferred.
In case you are working on a code base that you can't modify, you can set the {spring-framework-api}/beans/factory/support/AbstractBeanDefinition.html#PREFERRED_CONSTRUCTORS_ATTRIBUTE[`preferredConstructors` attribute] on the related bean definition to indicate which constructor should be used.
[[aot.bestpractices.factory-bean]]
=== FactoryBean
@@ -372,7 +383,7 @@ For instance, GraalVM needs to know ahead of time if a component uses reflection
Similarly, classpath resources are not shipped in a native image unless specified explicitly.
Consequently, if the application needs to load a resource, it must be referenced from the corresponding GraalVM native image configuration file.
The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.
The {spring-framework-api}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxies at runtime.
The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime within a native image:
[tabs]
@@ -410,7 +421,7 @@ It is also possible to register an implementation statically by adding an entry
[[aot.hints.reflective]]
=== `@Reflective`
{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
{spring-framework-api}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
For instance, `@EventListener` is meta-annotated with `@Reflective` since the underlying implementation invokes the annotated method using reflection.
By default, only Spring beans are considered and an invocation hint is registered for the annotated element.
@@ -424,7 +435,7 @@ If components other than Spring beans need to be processed, a `BeanFactoryInitia
[[aot.hints.register-reflection-for-binding]]
=== `@RegisterReflectionForBinding`
{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
{spring-framework-api}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` that registers the need for serializing arbitrary types.
A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.
`@RegisterReflectionForBinding` can be applied to any Spring bean at the class level, but it can also be applied directly to a method, field, or constructor to better indicate where the hints are actually required.
With `RuntimeHintsPredicates`, we can check for reflection, resource, serialization, or proxy generation hints.
This approach works well for unit tests but implies that the runtime behavior of a component is well known.
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {docs-graalvm}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
You can learn more about the global runtime behavior of an application by running its test suite (or the app itself) with the {graalvm-docs}/native-image/metadata/AutomaticMetadataCollection/[GraalVM tracing agent].
This agent will record all relevant calls requiring GraalVM hints at runtime and write them out as JSON configuration files.
For more targeted discovery and testing, Spring Framework ships a dedicated module with core AOT testing utilities, `"org.springframework:spring-core-test"`.
class for the configuration details involved in RAR deployment.
For a simple deployment of a Spring ApplicationContext as a Jakarta EE RAR file:
@@ -1046,7 +1050,7 @@ all application classes into a RAR file (which is a standard JAR file with a dif
file extension).
. Add all required library JARs into the root of the RAR archive.
. Add a
`META-INF/ra.xml` deployment descriptor (as shown in the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])
`META-INF/ra.xml` deployment descriptor (as shown in the {spring-framework-api}/jca/context/SpringContextResourceAdapter.html[javadoc for `SpringContextResourceAdapter`])
and the corresponding Spring XML bean definition file(s) (typically
javadoc for more detail. For more on AspectJ load-time weaving, see xref:core/aop/using-aspectj.adoc#aop-aj-ltw[Load-time Weaving with AspectJ in the Spring Framework].
and {spring-framework-api}/core/Ordered.html[`Ordered`] interfaces. See also the note on
xref:core/beans/factory-extension.adoc#beans-factory-programmatically-registering-beanpostprocessors[programmatic registration of `BeanPostProcessor` instances].
[NOTE]
@@ -272,8 +272,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop
However, you can only set this property if the `BeanFactoryPostProcessor` implements the
`Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should
consider implementing the `Ordered` interface, too. See the javadoc of the
The Spring Framework integrates with checkpoint/restore as implemented by https://github.com/CRaC/docs[Project CRaC] in order to allow implementing systems capable of reducing the startup and warmup times of Spring-based Java applications with the JVM.
Using this feature requires:
* A checkpoint/restore enabled JVM (Linux only for now).
* The presence of the https://github.com/CRaC/org.crac[`org.crac:crac`] library (version `1.4.0` and above are supported) in the classpath.
* Specifying the required `java` command-line parameters like `-XX:CRaCCheckpointTo=PATH` or `-XX:CRaCRestoreFrom=PATH`.
WARNING: The files generated in the path specified by `-XX:CRaCCheckpointTo=PATH` when a checkpoint is requested contain a representation of the memory of the running JVM, which may contain secrets and other sensitive data. Using this feature should be done with the assumption that any value "seen" by the JVM, such as configuration properties coming from the environment, will be stored in those CRaC files. As a consequence, the security implications of where and how those files are generated, stored, and accessed should be carefully assessed.
Conceptually, checkpoint and restore align with the xref:core/beans/factory-nature.adoc#beans-factory-lifecycle-processor[Spring `Lifecycle` contract] for individual beans.
== On-demand checkpoint/restore of a running application
A checkpoint can be created on demand, for example using a command like `jcmd application.jar JDK.checkpoint`. Before the creation of the checkpoint, Spring stops all the running beans, giving them a chance to close resources if needed by implementing `Lifecycle.stop`. After restore, the same beans are restarted, with `Lifecycle.start` allowing beans to reopen resources when relevant. For libraries that do not depend on Spring, custom checkpoint/restore integration can be provided by implementing `org.crac.Resource` and registering the related instance.
WARNING: Leveraging checkpoint/restore of a running application typically requires additional lifecycle management to gracefully stop and start using resources like files or sockets and stop active threads.
NOTE: If the checkpoint is created on a warmed-up JVM, the restored JVM will be equally warmed-up, allowing potentially peak performance immediately. This method typically requires access to remote services, and thus requires some level of platform integration.
== Automatic checkpoint/restore at startup
When the `-Dspring.context.checkpoint=onRefresh` JVM system property is set, a checkpoint is created automatically at
startup during the `LifecycleProcessor.onRefresh` phase. After this phase has completed, all non-lazy initialized singletons have been instantiated, and
`InitializingBean#afterPropertiesSet` callbacks have been invoked; but the lifecycle has not started, and the
`ContextRefreshedEvent` has not yet been published.
For testing purposes, it is also possible to leverage the `-Dspring.context.exit=onRefresh` JVM system property which
triggers similar behavior, but instead of creating a checkpoint, it exits your Spring application at the same lifecycle
phase without requiring the Project CraC dependency/JVM or Linux. This can be useful to check if connections to remote
services are required when the beans are not started, and potentially refine the configuration to avoid that.
WARNING: As mentioned above, and especially in use cases where the CRaC files are shipped as part of a deployable artifact (a container image for example), operate with the assumption that any sensitive data "seen" by the JVM ends up in the CRaC files, and assess carefully the related security implications.
NOTE: Automatic checkpoint/restore is a way to "fast-forward" the startup of the application to a phase where the application context is about to start, but it does not allow to have a fully warmed-up JVM.
If you prefer xref:integration/jms/namespace.adoc[XML configuration], you can use the `<jms:annotation-driven>`
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.