Spring Boot 3.4 Release Notes (original) (raw)

Upgrading from Spring Boot 3.3

RestClient and RestTemplate

Support for auto-configuring RestClient and RestTemplate to use Reactor Netty’s HttpClient or the JDK’s HttpClient has been added. In order of precedence, the supported clients are now:

Notably, if you don’t have an HTTP client library on the classpath, this will likely result in the use of JdkClientHttpRequestFactory where SimpleClientHttpRequestFactory would have been used previously. A particular client can be selected by setting spring.http.client.factory. Supported values are http-components, jetty, reactor, jdk, and simple.

All five clients will follow redirects by default. To disable this behavior, set spring.http.client.redirects to dont-follow.

Apache HTTP Components and Envoy

Apache HTTP Components have changed defaults in the HttpClient relating to HTTP/1.1 TLS upgrades. Most proxy servers handle upgrades without issue, however, you may encounter issues with Envoy or Istio.

If you need to restore previous behaviour, you can use the new ClientHttpRequestFactoryBuilder. Define a HttpComponentsClientHttpRequestFactoryBuilder and apply the following customization:

@Bean public HttpComponentsClientHttpRequestFactoryBuilder httpComponentsClientHttpRequestFactoryBuilder() { return ClientHttpRequestFactoryBuilder.httpComponents() .withDefaultRequestConfigCustomizer((builder) -> builder.setProtocolUpgradeEnabled(false));

Bean Validation of Configuration Properties

Previously, when a @ConfigurationProperties class annotated with @Validated was being validated using a Bean Validation implementation such as Hibernate Validator, validation of nested properties would be performed as they were bound, irrespective of the use of @Valid. In Spring Boot 3.4, validation now follows the behavior of the Bean Validation specification. Validation is performed from the @ConfigurationProperties-annoated class and only cascades down to nested properties where the corresponding field is annotated with @Valid.

When upgrading, inspect your @ConfigurationProperties classes with Bean Validation constraints. Add @Valid as necessary where you want the validation to cascade down to nested properties.

Bean-based Conditions

The behavior of @ConditionalOnBean and @ConditionalOnMissingBean has changed when used on a @Bean method and the annotation attribute is set. As before, both conditions will use the return type of the @Bean method as a default for the type to match. Previously, this default was not used if name, type, or value had been set. As of Spring Boot 3.4, this default will also not be used if annotation has been set. To restore the previous behavior, specify both a value that is the return type of the @Bean method and annotation.

Graceful Shutdown

Graceful shutdown of the embedded web server (Jetty, Rector Netty, Tomcat, or Undertow) is now enabled by default. If you need to restore the previous behavior, set server.shutdown to immediate.

Paketo tiny Builder for Building OCI Images

The default Cloud Native Buildpacks builder used when building OCI images for JVM applications using the Maven spring-boot:build-image goal or Gradle bootBuildImage task has changed from paketobuildpacks/builder-jammy-base to paketobuildpacks/builder-jammy-java-tiny. This should result in smaller images. The tiny builder does not include a shell, so it might not work for applications that require a start script to run the application. It also includes a reduced set of system libraries which, depending on your application, may not meet its needs. See the Maven or Gradle documentation for information on customizing the builder.

Dynamic Properties with Testcontainers

Support for defining dynamic properties by injecting a DynamicPropertyRegistry into a @Bean method has been deprecated and attempting to do so will now fail by default. Instead of injecting DynamicPropertyRegistry in a @Bean method, implement a separate @Bean method that returns a DynamicPropertyRegistrar. This separate bean method should inject the container from which the properties' values will be sourced. This addresses some container lifecycle issues and ensures that the container from which a property’s value has been sourced will have been started before the property is used.

If you wish to continue injecting DynamicPropertyRegistry (at the risk of encountering the lifecycle issue described above), set spring.testcontainers.dynamic-property-registry-injection to either warn or allow. The former will log a warning while allowing the use of an injected DynamicPropertyRegistry. The latter will silently allow the use of an injected DynamicPropertyRegistry, fully restoring Spring Boot 3.3’s behavior.

@AutoConfigureTestDatabase with Containers

The @AutoConfigureTestDatabase annotation now attempts to detect if a database has been sourced from a container. This should remove the need to add replace=Replace.NONE if you want to use the annotation with container databases.

If you need to revert to the old behavior, set replace=Replace.AUTO_CONFIGURED on the annotation.

Controlling Access to Actuator Endpoints

Support for enabling and disabling endpoints has been reworked, replacing the on/off support that it provided with a finer-grained access model. The new model supports only allowing read-only access to endpoint operations, in addition to disabling an endpoint (access of none) and fully enabling it (access of unrestricted).

The following properties have been deprecated:

Their replacements are:

Similarly, the enableByDefault attribute on @Endpoint has been deprecated with a new defaultAccess attribute replacing it.

As part of these changes, enabled-by-default is now applied consistently and irrespective of the use of @ConditionalOnEnabledEndpoint. If you lose access to an endpoint when upgrading, set management.endpoint.<id>.access to read-only or unrestricted or set management.endpoint.<id>.enabled to true to make the endpoint accessible again.

Additionally, a new property has been introduced that allows an operator to control the permitted level of access to Actuator endpoints:

This property caps any access that may have been configured for an endpoint. For example, if management.endpoints.access.max-permitted is set to read-only and management.endpoint.loggers.access is set to unrestricted, only read-only access to the loggers endpoint will be allowed.

Cloud Foundry ConditionalOnAvailableEndpoint Exposure

The EndpointExposure.CLOUD_FOUNDRY enum value used with the @ConditionalOnAvailableEndpoint has been deprecated in favor of EndpointExposure.WEB. Typical Spring Boot application will probably not be affected by this change, however, if you have custom Cloud Foundry specific actuator endpoint beans you should update your conditions to use EndpointExposure.WEB.

HtmlUnit 4.5

HtmlUnit has been upgraded to 4.5. With this upgrade comes a change in dependency coordinates from net.sourceforge.htmlunit:htmlunit to org.htmlunit:htmlunit and a change in package names from com.gargoylesoftware.htmlunit. to org.htmlunit.. When upgrading, update your build configuration and imports accordingly.

Selenium HtmlUnit 4.25

Selenium HtmlUnit has been updated to 4.25. With this upgrade comes a change in dependency coordinates from org.seleniumhq.selenium:htmlunit-driver to org.seleniumhq.selenium:htmlunit3-driver. When upgrading, update your build configuration accordingly.

WebJars Locator Integration

OkHttp Dependency Management Removed

Spring Boot no longer depends on OkHttp so it no longer manages its version. If your application has OkHttp dependencies, update its build to use an OkHttp version that meets its needs.

Netty in Native Image

Note This is not needed when upgrading directly to Spring Boot 3.4.1 or later.

Spring Boot 3.4.0 uses a version of Netty which isn’t supported yet by the GraalVM reachability metadata included in the Native Build Tools. To get Netty working in a native image, you’ll need to upgrade the GraalVM reachability metadata version manually.

For Maven:

org.graalvm.buildtools native-maven-plugin 0.3.14

For Gradle:

graalvmNative { metadataRepository { version = '0.3.14' } }

Deprecation of @MockBean and @SpyBean

@MockBean and @SpyBean have been deprecated in favor of @MockitoBean and @MockitoSpyBean in Spring Framework. The functionality provided by the Spring Framework annotations is not exactly the same as that offered by Spring Boot. For example, @MockitoBean is not supported on @Configuration classes and you may need to migrate to annotating fields on a test class instead.

Tomcat APR

If you’re using Tomcat’s APR and you’re running on Java >= 24, you have to set the property server.tomcat.use-apr to when-available or always. This property has been introduced with Spring Boot 3.4.4 and defaults on Java >= 24 to never. On Java < 24 this property defaults to when-available. See #44033 for more details.

Empty YAML Maps

Empty maps are now ignored when processing YAML configuration. This allows all values in the Environment to be scalar, aligning YAML configuration with other formats such as properties files and system properties. See [#35403](https://github.com/spring-projects/spring-boot/issues/35403) for further details.

Deprecations from Spring Boot 3.2

Classes, methods, and properties that were deprecated in Spring Boot 3.2 and marked for removal in 3.4 have been removed in this release. Please ensure that you aren’t calling deprecated methods before upgrading.

Minimum Requirements Changes

Gradle

Gradle 7.5, 8.0, 8.1, 8.2 and 8.3 are no longer supported. Gradle 7.x (7.6.4 or later) or Gradle 8.x (8.4 or later) is now required.

New and Noteworthy

Structured Logging

Support for structured logging has been introduced with built-in support for Elastic Common Schema (ecs), Graylog Extended Log Format (gelf) and Logstash (logstash). To enable structured file logging set logging.structured.format.file to ecs, gelf or logstash. Similarly, to enable structured console logging set logging.structured.format.console.

To learn more about Spring Boot’s support for structured logging, including how to define a custom format, see the reference documentation.

@Fallback Beans

@ConditionalOnSingleCandidate now supports @Fallback beans. The condition will match if there’s a single primary bean or, if there are no primary beans, if there’s a single non-fallback bean.

Defining Additional Beans

When type matching, bean-based conditions will now ignore any beans that are not default candidates. By declaring that a bean is not a default candidate (using @Bean(defaultCandidate=false)), a bean of an auto-configured type can now be defined without causing the auto-configure bean of the same type to back off. This reduces the configuration required to, for example, use two DataSource beans or two EntityManagerFactory beans in the same application.

ClientHttpRequestFactory Builders

A new ClientHttpRequestFactoryBuilder interface has been added which allows you to build ClientHttpRequestFactory instances for specific technologies. Builders allow for fine-grained customization of the underlying components, as well as a consistent way to apply common settings.

The following builders can be created for specific libraries using static factory methods from the interface:

See the updated reference docs for more details, including how to apply common settings using configuration properties.

Observability Improvements

Application Groups

The new spring.application.group property can be used to group applications together, for example if they all belong to some business unit or one bigger application arrangement. When this property is set, it’s also included in the log messages. This behavior can be controlled with the property logging.include-application.group. The application group is also automatically added to the OpenTelemetry Resource.

OTLP

It’s now possible to send OTLP spans over the gRPC transport. For this, set the new configuration property management.otlp.tracing.transport to grpc. This property defaults to http. Service connection support for this has been added, too.

The new properties under management.otlp.logs can be used to auto-configure OpenTelemetry’s OtlpHttpLogRecordExporter and SdkLoggerProvider.

Other Observability Updates

The ProcessInfoContributor now also shows memory info about heap and non-heap usage.

New management.otlp.tracing.export.enabled, management.wavefront.tracing.export.enabled and management.zipkin.tracing.export.enabled properties can now be used to enable or disable trace exporting more finely grained.

AssertJ Support for MockMvc

Auto-configuration for MockMvcTester is provided when AssertJ is on the classpath.MockMvcTester lets you define the requests and the assertions using a fluent API. It can be injected anywhere MockMvc is.

For more details, see the dedicated section of the Spring Framework reference documentation.

Spring Pulsar

Configuration properties are now provided for configuring a default tenant and namespace. The defaults apply when consuming or producing messages with a topic URL that is not fully qualified. Configure them using the spring.pulsar.defaults.topic.tenant and spring.pulsar.defaults.topic.namespace configuration properties or define your own PulsarTopicBuilder bean. Set spring.pulsar.defaults.topic.enabled=false to disable the defaults.

A new PulsarContainerFactoryCustomizer interface has been added to support customization of the auto-configured PulsarContainerFactory.

The spring.pulsar.consumer.subscription.name configuration property now applies to the auto-configured Pulsar listener container.

Two new configuration properties for configuring the Pulsar client’s concurrency have been introduced:

Lastly, the new spring.pulsar.listener.concurrency property can be used to control the concurrency of the auto-configured Pulsar message listener container.

Couchbase Authentication

Client certificates can now be used to authenticate with a Couchbase cluster, as an alternative to basic username and password authentication. See the reference documentation for more details.

FreeMarker

FreeMarker variables that are used by the auto-configured FreeMarker’s Configuration object can now be customized. To do so, define one or more beans of type FreeMarkerVariablesCustomizer. These are invoked according to their defined order (if any).

Embedded Broker support with ActiveMQ Classic

Now that ActiveMQ Classic supports an embedded broker again, the auto-configuration has been updated to support it.

Note that contrary to Spring Boot 2.7.x, the ActiveMQ starter is client only. To use the embedded broker, org.apache.activemq:activemq-broker should be added to your application.

Configuration Metadata

The default value of an Enum is now detected by the annotation processor. If you have added manual metadata to provide the value for a custom property, make sure to remove it.

Deprecating and Replacing Auto-configuration Classes

To make it easier to evolve auto-configuration, support for deprecating and replacing auto-configuration classes has been introduced. Replacements can be declared in a new META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements file. To learn more, please refer to the reference documentation.

Base64 Resource Support and Automatic ProtocolResolver registration

Any property resolved to a Resource can now make use of the Base64ProtocolResolver without needing to explicitly register it. For example, you can now use it to specify the certificate location of a SAML2 relying party signing credential:

spring: security: saml2: relyingparty: registration: keycloak: entity-id: "saml-test" signing: credentials: - private-key-location: classpath:local.key certificate-location: base64:LS...

You can also easily add your own protocol resolvers by adding them to a META-INF/spring.factories file under the org.springframework.core.io.ProtocolResolver key.

Virtual Threads

If virtual threads are enabled, the following components will now use them:

Image Building Improvements

A trustBuilder option has been added to the Maven and Gradle plugins for building OCI images. This option controls how the CNB lifecycle is invoked, providing improved security when using builders from untrusted sources. By default, builders from the Paketo project, Heroku, and Google are trusted. See the Maven or Gradle documentation for information.

An imagePlatform option has been added to the Maven and Gradle plugins for building OCI images. This option can be used to specify the operating system and architecture of any CNB builder, run, and buildpack images that are pulled in order to run CNB buildpacks. This can be used to build an image for an operating system and architecture that is different from the OS/architecture of the host platform, when the host platform supports emulation of the other OS/architecture (for example, when using Rosetta on a Mac with Apple silicon to emulate the AMD archicture on an ARM host). See the Maven or Gradle documentation for more information.

Docker Compose Improvements

Docker Compose now supports multiple Docker Compose configuration files.

Command Line Arguments

The new properties spring.docker.compose.start.arguments and spring.docker.compose.stop.arguments can be used to specify additional command line arguments that are passed to the Docker Compose subcommands when starting and stopping services. A new spring.docker.compose.arguments property has been added to pass arguments to Docker Compose.

Updated Support

Testcontainers Improvements

Actuator

Pluggable Actuator Exposers

It is now possible to extend Spring Boot to expose actuator endpoints in a pluggable way. The new EndpointExposureOutcomeContributor interface can be implemented to influence @ConditionalOnAvailableEndpoint conditions.

This extension should make it easier to offer additional platform integrations similar to our existing Cloud Foundry support.

SSL information and health check

If you’re using SSL bundles, there’s now a new endpoint showing SSL information (validity dates, issuer, subject, etc.) available under /actuator/info. This endpoint also shows soon to be expired certificates to alert you that they need to be rotated soon. There’s a new configuration property named management.health.ssl.certificate-validity-warning-threshold to configure the threshold.

A new health check monitoring the SSL certificates has been added, too. If a certificate is invalid, it sets the status to OUT_OF_SERVICE.

Additional info in /actuator/scheduledtasks endpoints

The /scheduledtasks Actuator endpoint now exposes additional metadata about scheduled tasks, such as "next scheduled execution time" and "last execution time, status and exception".

Miscellaneous

Apart from the changes listed above, there have also been lots of minor tweaks and improvements including:

Deprecations in Spring Boot 3.4