This commit makes sure that `@ExceptionHandler`-annotated methods can be
invoked via reflection in a native image. As most of the handling of
the parameter and the return type is shared with our generic
RequestMapping handling, the ReflectiveProcessor extends from it.
An `@ExceptionHandler`-annotated method can return a `ProblemDetail`. If
that's the case, reflection entries are contributed.
Closes gh-29297
This commit improves the exception message thrown by MultipartParser
when it cannot find the end of the multipart body, by showing in the
message what the parser is looking for (CRLF--<boundary>).
Closes gh-28067
This commit also removes ResourcePropertiesPersister which
was introduced in 5.3 specifically for spring.xml.ignore
flag and which is expected to be used only internally by
Spring Framework. DefaultPropertiesPersister should be used
instead.
Closes gh-29277
This commit introduces support for CBOR and Protobuf using Kotlin
serialization. Support comes in the form of Encoder/Decoder as well
as HttpMessageConverters. Seperate abstract base classes supply support
for binary and string (de)serialization.
The exising JSON codecs and message converters have been migrated to
use the new base classes.
Closes gh-27628
Prior to this commit, the Observation filter for Servlet applications
would only use the request pathInfo as an "http.url" high cardinality
keyvalue. This commit ensures that we're using the full request URL as a
value there.
This also polishes gh-29254.
Fixes gh-29257
See gh-29254
This commit changes the new high cardinality key value from
"uri.expanded" to "http.url" in order to align with the OTel
specification, since there is no need for backwards compatibility on
this new metadata.
Closes gh-29254
Prior to this commit, the `RestTemplate` `ClientHttpObservation` would
be started before the request object is available. While this would also
measure the connection estalishment for some HTTP client libraries, this
arrangement is incompatible with a tracing approach where the request
must be available to propagate information through the request headers.
This commit ensures that the observation only starts when the request is
available.
Fixes gh-29234
Prior to this commit, the HTTP Observations would use
`HttpStatus.Series` as a value source for the "outcome" key value in
recorded observations. This would work for most cases, but would not
align in the 2xx HTTP status cases: the series would provide a
"SUCESSFUL" value whereas the heritage metrics support in Spring Boot
would give "SUCESS".
This commit introduces a dedicated `HttpOutcome` concept for this and
applies it to all HTTP observations.
Fixes gh-29232
This commit ensures that all HTTP `ObservationConvention`
implementations provide a consistent contextual name for observations.
This name should be like "http get" where only the HTTP verb changes
depending on the request.
Fixes gh-29231
This commit also temporarily changes a test assertion for the Jackson
Kotlin module.
As of https://youtrack.jetbrains.com/issue/KT-52932, Kotlin enhanced the
`IntRange` and this change is not supported yet by the Jackson Kotlin
module. An issue has been reported here:
FasterXML/jackson-module-kotlin#582
Closes gh-29225
Improve ResponseCookie to allow an existing instance to be mutated
and also to set the cookie value through the builder. This allows
CookieLocaleResolver to avoid duplicating all the fields of
ResponseCookie and to have only a ResponseCookie field instead.
Closes gh-28779
At present, CookieLocaleResolver extends CookieGenerator instead of
AbstractLocale(Context)Resolver like other LocaleResolver
implementations. This means it duplicates some common aspects of
LocaleResolver hierarchy while also exposing some CookieGenerator
operations, such as #addCookie and #removeCookie.
Additionally, CookieGenerator's support for writing cookies is based
on Servlet support which at current baseline doesn't support SameSite
directive.
This commit refactors CookieLocaleResolver to make it extend
AbstractLocaleContextResolver and also replaces CookieGenerator's
cookie writing support with newer and more capable ResponseCookie.
Simplify creation of CookieLocaleResolver with custom cookie name
This commit introduces CookieLocaleResolver constructor that accepts
cookie name thus allowing for a simpler creation of an instance with
the desired cookie name.
See gh-28779
This commit isolates the invocation of Kotlin coroutines into a separate
template method, so that it can be overridden in subclasses of
RequestMappingHandlerAdapter.
Closes gh-27195
Prior to this commit, `ServletContextResource` could rely on
`ServletContext#getRealPath` to check whether a resource exists.
This behavior is not enforced on some Servlet containers, as this method
is only meant to translate virtual paths to real paths, but not
necessarily check for the existence of the file.
See https://bz.apache.org/bugzilla/show_bug.cgi?id=55837#c3 for a
rationale of this behavior in Tomcat.
This commit enforces an additional check, resolving the path as a `File`
and checking that is exists and is a file.
Closes gh-26707
In general, `Stream#toList()` is not a transparent replacement for
`.collect(Collectors.toList()))`, as the former returns an immutable
list.
This commit reverts some of those changes, where the returned `List`
instance was expected to be mutable.
See gh-29203
After gh-29068, some Type instances can throw an
IllegalArgumentException. This commit catches them
properly to just return a null serializer in that
case.
Closes gh-29192
This commit removes the scoping of `RestTemplate` requests, since no
user code is meant to run during HTTP client exchanges.
This also polishes the reactive `WebFilter` to directly use the
specific enum when creating the observation.
Prior to this commit, resource management around
`ClientHttpRequestFactory` and `RestTemplate` was unclear. Some
factories implementation were implementing a `DisposableBean` and other
contracts were not managing request factory resources.
In the meantime, neither `ClientHttpRequestFactory` nor `RestTemplate`
are typically meant to be contributed as beans to the application
context. Most often, they're instantiated within beans and their
lifecycle should be managed by those.
This commit makes all `ClientHttpRequestFactory` `Closeable` and ensures
that all existing implementations have a similar behavior between
`dispose()` and `close()`. Since `RestTemplate` (actually
`HttpAccessor`) can instantiate factories on its own, they also now
extend `Closeable` to properly close those resources, if not externally
managed.
Closes gh-29010
This commit introduces a `HttpRequestsObservationWebFilter` which
instruments web frameworks using Spring's reactive `ServerHttpRequest`
and `ServerHttpResponse` interfaces.
This replaces Spring Boot's `MetricsWebFilter`.
See gh-28880
This commit introduces the new `HttpRequestsObservationFilter`
This `Filter` can be used to instrument Servlet-based web frameworks for
Micrometer Observations. While the Servlet request and responses are
automatically used for extracting KeyValues for observations, web
frameworks still need to provide the matching URL pattern, if supported.
This can be done by fetching the observation context from the request
attributes and contributing to it.
This commit instruments Spring MVC (annotation and functional variants),
effectively replacing Spring Boot's `WebMvcMetricsFilter`.
See gh-28880
This commit introduces Micrometer as an API dependency to the spring-web
module. Micrometer is used here to instrument `RestTemplate` and record
`Observation` for HTTP client exchanges.
This will replace Spring Boot's `MetricsClientHttpRequestInterceptor`
which uses the request interceptor contract for instrumentation.
This approach is limited as measurements and tags aren't always precise
and overhead is more important than a direct instrumentation.
See gh-28341
This commit extracts Mock HTTP client request and response for the
imperative variant. These are made available in the testFixtures
configuration for shared usage.
Update StreamUtils.drain to use InputStream.transferTo with a null
OutputStream. This avoids allocating buffers for cases where the
supplied InputStream has an optimized transferTo method (e.g.,
ByteArrayInputStream and FileInputStream).
Additionally, update StreamUtils.emptyInput to simply call
InputStream.nullInputStream.
Closes gh-28961
This commit renames registerResourceIfNecessary() to registerResource()
and throws an exception if the class path resource does not exist.
Closes gh-29083
As of Java 18, the serial lint warning in javac has been expanded to
check for class fields that are not marked as `Serializable`.
See https://www.oracle.com/java/technologies/javase/18all-relnotes.html#JDK-8202056
In the Spring Framework codebase, this can happen with `Map`, `Set` or
`List` attributes which are often assigned with an unmodifiable
implementation variant. Such implementations are `Serializable` but
cannot be used as field types.
This commit ensures that the following changes are applied:
* fields are marked as transient if they can't be serialized
* classes are marked as `Serializable` if this was missing
* `@SuppressWarnings("serial")` is applied where relevant
`HttpStatusCode` instance only hold an int value and are held by
`Serializable` classes, so this commit enforces this.
Without this change, Java 19+ will emit a compiler warning as
`Serializable` classes use `HttpStatusCode` as a field.
This commit ensures that when using `sendRedirect`, the response wrapper
behaves correctly with regards to the Servlet specification:
1. reset the response buffer to clear any partially written response
2. set the expected response HTTP headers
3. flush the buffer to commit the response
Closes gh-29050
This commit makes sure that quoted pairs, as used in Content-Disposition
header file names (i.e. \" and \\), are properly decoded, whereas before
they were stored as is.
Closes gh-28837
Since Spring no longer adds the SynthesizedAnnotation interface to the
JDK dynamic proxy used to synthesize an annotation, this commit
officially deprecates SynthesizedAnnotation and related methods in
RuntimeHintsUtils.
See gh-29041, gh-29054
Closes gh-29053
This commit fixes Kotlin Serialization converter
registration logic in RestTemplate,
AbstractMessageBrokerConfiguration and
AllEncompassingFormHttpMessageConverter classes
to be similar to the one in
WebMvcConfigurationSupport.
Closes gh-29008
This commit fixes a race condition in PartGenerator, used by
DefaultPartHttpMessageReader. The condition can occur when a
completion signal comes in, and the state is changed to IdleFileState
at the same time.
Closes gh-28963
This commit introduces support for Netty 5's Buffer, in the form of
Netty5DataBuffer. Because of the new API offered by Buffer, several
changes have been made to the DataBuffer API:
- CloseableDataBuffer is a simpler alternative to PooledDataBuffer, and
implemented by Netty5DataBuffer. DataBufferUtils::release can now
handle CloseableDataBuffer as well as PooledDataBuffer.
- PooledDataBuffer::touch has been moved into a separate interface:
TouchableDataBuffer, which is implemented by Netty5DataBuffer.
- The capacity of DataBuffers can no longer be reduced, they can only
grow larger. As a consequence, DataBuffer::capacity(int) has been
deprecated, but ensureWritable (formally ensureCapacity) still exists.
- DataBuffer::slice and retainedSlice have been deprecated in favor of
split, a new method that ensures that memory regions do not overlap.
- DataBuffer::asByteBuffer has been deprecated in favor of toByteBuffer,
a new method that returns a copy, instead of shared data.
- DataBufferFactory::allocateBuffer has been deprecated in favor of
allocateBuffer(int).
Closes gh-28874
This commit harmonizes the registration of an executable so that
the default method and the method that takes an empty customizer
produces the same hint. The same applies to the readable flag of
a field hint.
Rather than returning a list of executable modes, the "highest" mode
is retained.
See gh-29011
Based on the feedback in #28977 an easy way to create a list of
type references based on a vararg of classes is helpful when
registering the same hints for several types.
This commit updates RuntimeHintsUtils to focus on registering a JDK
proxy only as annotations of annotated elements that have at least
an introspection hints are visible out-of-the-box.
This commit also removes unnecessary hints and adapt `@Reflective` to
detect if a hint is required using the introduced
MergedAnnotation#isSynthesizable.
See gh-28967
Includes runtime storing of generated classes to a directory specified by the "cglib.generatedClasses" system property. Avoids lazy CGLIB fast-class generation and replaces generated Enhancer and MethodWrapper key classes with equivalent record types. Introduces support for early type determination in InstantiationStrategy, AopProxy and SmartInstantiationAwareBeanPostProcessor - in order to trigger CGLIB class generation in refreshForAotProcessing (through early determineBeanType calls for bean definitions).
Closes gh-28115
This commit correctly identifies MaxUploadSizeExceededException in
StandardMultipartHttpServletRequest by converting keywords in the
exception message to lowercase before checking for their presence, for
compatibility with Jetty 9.4.x.
Closes gh-28759