BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Spring Framework 6.2 and Spring Boot 3.4 Improve Containers, Actuators Ahead of New 2025 Generations

Spring Framework 6.2 and Spring Boot 3.4 Improve Containers, Actuators Ahead of New 2025 Generations

VMware released Spring Framework 6.2 and Spring Boot 3.4 in November 2024, keeping the Java 17 and Jakarta EE 9 baselines. Spring Boot 3.4 has structured logging, adds various container images to Docker Compose and Testcontainers, and improves container image building and actuators. VMware also announced Spring Framework 7 and Spring Boot 4 for November 2025, which will stick with Java 17 but move to Jakarta 11, adopt JSpecify for null-safety, and speed up application startup with Project Leyden. InfoQ spoke to Spring Framework project lead Juergen Hoeller and Spring Framework core committer Sébastien Deleuze about these 2025 releases.

The log output has a well-defined, often machine-readable format in structured logging. Spring Boot supports the Elastic Common Schema (ecs), Logstash (logstash), and the Graylog Extended Log Format (gelf) formats. Setting logging.structured.format.file to one of these three values starts structured file logging while logging.structured.format.console defines the structured console logging format.

Docker Compose can receive command-line arguments through the new properties spring.docker.compose.start.arguments and spring.docker.compose.stop.arguments and handles the POSTGRES_HOST_AUTH_METHOD=trust environment variable. Spring Boot added various container images to Docker Compose and Testcontainers: Redis Stack and Redis Stack Server with redis/redis-stack and redis/redis-stack-server, Grafana LGTM with grafana/otel-lgtm and the LgtmStackContainer class for Testcontainers. Kafka support is now in Testcontainers with the KafkaContainer class.

Building OCI images using builders from untrusted sources is now more secure through the trustBuilder (see the documentation for Maven and Gradle). The imagePlatform option can build a container image for an operating system and architecture that is different from those of the host platform. The default Cloud Native Buildpacks builder for JVM applications is now paketobuildpacks/builder-jammy-java-tiny, which should result in smaller images. It supports ARM and x64 out of the box.

A new read-only actuator access mode joins the two existing, renamed modes called "access of unrestricted" (was enabled) and "access of none" (was disabled). That's why management.endpoints.enabled-by-default is called management.endpoints.access.default, and management.endpoint.<id>.enabled is management.endpoint.<id>.access. A new actuator endpoint under /actuator/info shows SSL information, including certificates that will soon expire. The /scheduledtasks endpoint shows more information about scheduled tasks, such as "next scheduled execution time" and "last execution time, status, and exception."

Embedded web servers now gracefully shut down by default. Setting server.shutdown to immediate reverses that change. The Undertow web server uses virtual threads if enabled. RestClient and RestTemplate can now use any of the following five HTTP clients, in order of preference: Apache HTTP Components (HttpComponentsClientHttpRequestFactory), Jetty Client (JettyClientHttpRequestFactory), Reactor Netty HttpClient (ReactorClientHttpRequestFactory), JDK HttpClient (JdkClientHttpRequestFactory), and Simple JDK HttpURLConnection (SimpleClientHttpRequestFactory).

After ActiveMQ Classic supports an embedded broker again, Spring Boot can auto-configure it once more with org.apache.activemq:activemq-broker. Contrary to Spring Boot 2.7.x, the ActiveMQ starter is client only. The observability property spring.application.group combines applications that are part of a bigger unit. Docker Compose and Testcontainers support has been added for OTLP logging.

Spring Boot no longer depends on the OkHttp library, so users who need it must now manage the version themselves. The @MockBean and @SpyBean annotations were deprecated in favor of Spring Framework's @MockitoBean and MockitoSpyBean. Spring Boot 3.4 only works with the Gradle 7.6.4 and Gradle 8.4.0 release trains or later.

Notable Spring dependency upgrades in Spring Boot 3.4 include Spring Security 6.4, Spring Session 3.4, Spring Integration 6.4, Spring Batch 5.2, and Spring for Apache Kafka 3.3. Noteworthy third-party dependency upgrades include Log4j 2.24, Liquibase 4.29, Flyway 10.20, MySQL 9.1.0, MongoDB 5.2.0, Hibernate 6.6, Reactor 2024.0.0, Kafka 3.8, Jackson 2.18, Apache Http Client 5.4, Micrometer 1.14, HtmlUnit 4.3.0, Selenium 4.25.0, Mockito 5.13, JUnit Jupter 5.11, and Testcontainers 1.20.3.

Spring Framework 6.0 and 6.1 and Spring Boot 3.0 and 3.2 had more user-facing features, such as Ahead-of-Time compilation with GraalVM Native Image or support for virtual threads and CRaC. Spring Framework 6.2 and Spring Boot 3.4 lack such headline-grabbing features. That's not uncommon for the last year of a Spring Framework generation: There was no Spring Framework release at all in 2021 before 6.0 came out in 2022.

Juergen Hoeller, Spring Framework project lead, recently announced the new Spring Framework 7 and Spring Boot 4 generations for November 2025. They will retain the JDK 17 baseline but "embrace the upcoming JDK 25 LTS," which is expected to launch two months earlier. The Kotlin baseline moves to Kotlin 2, and the Jakarta EE baseline moves from 9 to 11, which brings Tomcat 11, Hibernate ORM 7, and Hibernate Validator 9. The Spring projects will also adopt JSpecify for null-safety.

Juergen Hoeller and Sébastien Deleuze, Spring Framework core committer at VMware, kindly answered InfoQ questions.

InfoQ: Spring Framework 6 is the shortest generation since 2.0 also ended after three years in 2009. Why?

Juergen Hoeller: Historically, our framework generations have been driven by individual factors at their time. We never aimed for a specific lifetime of a generation, rather for certain feature scoping that triggered a new release. For the same reason, our minor release cadence was typically once a year, but occasionally skipping a year. Long-term support was offered for the last feature release of each generation; that remained true across the years.

Going forward, we are adapting to industry trends where predictable releases and, in particular, a predictable long-term support cadence become the norm. Not least of it all, we are adapting to the more frequent JDK cadence and to more frequent major releases among our third-party dependencies. As a consequence, we are less scope-driven but rather time-driven these days, primarily for Spring Boot but also for Spring Framework

InfoQ: Spring Framework 6 required JDK 17, which was one year old at the time. Spring Framework 7 will keep Java 17 as its baseline, not using the then two-year-old JDK 21. Why does Spring 7 keep the previous generations' Java baseline for the first time since 2.0 did so in 2006?

Hoeller: Our baseline is usually derived from technical concerns. Java 17 provided so much goodness over Java 11 (the alternative choice at the time) that we went with it for Spring Framework 6.0 right away, dramatically modernizing our codebase and pushing the industry overall - at the expense of making the upgrade path harder, in combination with the Jakarta EE namespace change at the same time.

For Spring Framework 7.0, there is hardly any technical benefit in a Java baseline upgrade. Specific features against newer Java versions can easily be provided through multi-release jars, as we do for Virtual Threads in Java 21 already. The current industry consensus is clearly around a Java 17 baseline, for example, with the Jakarta EE 11 APIs and the upcoming provider generation there. Since our current framework codebase would not benefit from a baseline upgrade, we are aiming to stay on a Java 17 baseline while providing first-class support for Java 21 as well as Java 25 in the same generation. Instead, our baseline raise comes with Jakarta EE 11 APIs, such as Jakarta Servlet 6.1 and Jakarta Persistence 3.2, as well as Kotlin 2.

We generally recommend the latest Java LTS generation for production deployment, independent from the underlying baseline, which is effectively just a technical minimum that the framework tolerates at runtime. For Spring Framework 7.0, despite a Java 17 baseline, our focus is clearly on embracing Java 25. Looking forward, we can see Java 25 becoming an attractive new baseline for the wider Java ecosystem at a later point. However, for the time being, the best we can do is to support it as part of our JDK version range.

InfoQ: The Spring 7 announcement mentioned JSpecify, which standardized annotations for null safety. How is null safety exposed in Spring Framework 6 and Spring Boot 3 today? And what changes can we expect in Spring Framework 7 and Spring Boot 4?

Sébastien Deleuze: Spring Framework 6 provides null-safety annotations like @Nullable in the org.springframework.lang package. Those annotations are meta-annotated with JSR 305 annotations (a dormant but widespread JSR), letting tooling vendors like IDEA or Kotlin provide null-safety support in a generic way.

In Spring Framework 7, we will tentatively migrate to JSpecify annotations, an industry-wide effort where the Spring team has been involved for multiple years, and deprecate Spring null-safety annotations.

The migration to JSpecify should bring various improvements, such as:

  • Proper specifications for tooling vendors and documentation for end-users.
  • No more split-package caused by the JSR 305 annotations, impacting JPMS compatibility.
  • Better Kotlin integration.
  • Capability of specifying generic type, array and varargs element null-safety.
  • Usable by other libraries not based on Spring, for example, Reactor and Micrometer.

We also intend to comprehensively specify API null-safety in further Spring portfolio projects.

InfoQ: The announcement of Spring 7 mentioned a "strategic alignment with GraalVM and Project Leyden." What makes this alignment strategic?

Deleuze: Our alignment with GraalVM and Project Leyden is strategic for three main reasons.

First, they are complementary. GraalVM provides huge benefits like instant startup/warm-up at the cost of significant constraints like long build time and compatibility issues. Project Leyden's AOT cache provides great benefits like 3x to 4x faster startup time - maybe not as dramatic as GraalVM native images, but enough for many users and with very few side effects when Spring Boot dedicated support is used. Focusing on those two technologies will supercharge the efficiency of Spring Boot 4 applications for many deployment scenarios.

Second, the Spring team has active R&D collaborations with both teams, illustrated by the recent joint talks with the Java Platform team on Project Leyden and with the GraalVM team on native images at Devoxx Belgium 2024.

Third, it is also strategic in the sense that we focus most R&D effort on those technologies to provide two golden paths to Spring developers who ask for guidance. Both can take advantage of Spring Ahead-Of-Time optimizations and Buildpacks. We expect Project Leyden's AOT cache to be the successor of Class Data Sharing (CDS), which we currently support as of Spring Boot 3.3.

At this point, we don't plan significant further effort on Project CRaC, which tends to be harder to leverage for our users - see this comparison. So, with Project Leyden's AOT cache on the JVM (and CDS in the interim) as well as native images based on GraalVM, we are working toward two mainstream efficiency options for the Spring Boot 4 generation.

For more information, see the release notes for Spring Framework 6.2 and Spring Boot 3.4.

About the Author

Rate this Article

Adoption
Style

BT