Release Radar: Spring, Kotlin, IntelliJ... and Advent Calendars - JVM Weekly vol. 110
This week: Release Radar. But I've problably never had such packed one.
1. News from the Spring Ecosystem: Spring Boot, Spring Framework, and More
November is traditionally the time for new Spring releases, and 2024 is no exception. Today's radar edition kicks off with Spring updates, as both Spring Framework 6.2, Spring Boot 3.4, and a few other projects were released.
First, let's recall the difference between Spring Framework and Spring Boot, as over the years, the distinction between these projects has sometimes blurred. Spring Framework is a comprehensive toolkit and library for building Java applications, offering great flexibility but requiring manual configuration. In contrast, Spring Boot can be seen as an "opinionated" overlay for Spring Framework that simplifies application development through auto-configuration and an embedded application server, enabling a quick project start. Spring Boot inherits many innovations from Spring Framework, so we will begin with the latter.
Spring Framework 6.2
Spring Framework 6.2 doesn't bring revolutionary changes but introduces several improvements that directly enhance the developer experience. For instance, the new @Fallback annotation elegantly addresses the common issue of default implementation configurations—users no longer need to add @Primary to their beans, which often led to unexpected conflicts in larger applications. Changes in the autowiring algorithm now prioritize parameter name matching and @Qualifier, creating more predictable and debuggable dependency injection configurations. For native applications, the new annotations @RegisterReflection and @ReflectionScan significantly simplify the reflection configuration process in GraalVM, which has been one of the biggest challenges in migrating to native apps.
The framework also improves testing support. Native support for AssertJ in MockMvc enables the use of fluent APIs and more readable assertions, eliminating the need for the less intuitive Hamcrest (Good night, sweet prince—though I personally enjoy AssertJ for its excellent support for testing JSON). New URL parsers (compliant with RFC 3986 and based on the URL Living Standard) give developers better control over URL processing—particularly important for applications that must handle both strict REST APIs and user-entered addresses in browsers.
On the architectural level, improved support for rendering HTML fragments simplifies integration with libraries like htmx (which we covered in Foojay.io's recent round-up) or Turbo, allowing for dynamic interface building without complex JavaScript.
More changes are documented in the release notes.
However, it's clear that Spring Framework 6.2 serves as a stepping stone toward the major Spring Framework 7.0 update coming in November 2025. Version 7.0 will introduce support for Jakarta EE 11 (including Tomcat 11, Hibernate ORM 7), JDK 25 LTS, Kotlin 2.0, null-safety according to JSpecify, and enhancements to Spring AOT with GraalVM and Project Leyden integration. It will also revise JPA and JMS support, deprecating outdated features. The first test version of 7.0 will appear in early 2025, forming the foundation for Spring Boot 4.0.
Spring Boot 3.4
Moving to Spring Boot, let's explore the innovations in Spring Boot 3.4 (in addition to the previously mentioned framework updates). It introduces improved support for HTTP clients such as RestClient and RestTemplate, enabling automatic configuration with libraries like Apache HTTP Components, Jetty, Reactor Netty, or JDK HttpClient. Key changes include default behaviors for redirects and the ability to select clients through the property spring.http.client.factory. It also introduces support for spring-boot:build-image with native GraalVM images for Apple Silicon/ARM 64.
In configuration and validation, updates ensure closer alignment with Bean Validation specifications. Nested properties in @ConfigurationProperties now require explicit @Valid annotations for cascading validation, providing greater precision in managing validation rules. Changes to conditional annotations like @ConditionalOnBean improve logic handling, reducing ambiguities in component definitions. These updates, like those in Spring Framework 6.2, establish clear rules for configuration management and mitigate the risk of errors from implicit behaviors.
Spring Boot 3.4 also enhances observability features, including structured logging with support for formats like Elastic Common Schema (ECS), GELF, and Logstash. A new property, spring.application.group, allows better application grouping and improved telemetry support with OpenTelemetry (OTLP). These improvements facilitate log management and application monitoring, accelerating issue analysis and resolution. Additionally, Actuator endpoints now provide richer metadata and support pluggable exposers, simplifying integration with custom platforms, while SSL monitoring enables earlier detection of certificate issues.
In the realm of BuildPacks, the Paketo Tiny Builder allows the creation of smaller JVM container images, positively impacting performance and resource utilization. Improvements also include support for virtual threads, better Docker Compose integration, and enhanced Testcontainers support. Expanded platform support includes Redis Stack, Kafka, and Hazelcast.
Spring Modulith 1.3
Without covering all related Spring sub-projects, we'll conclude with the youngest member of the family: Spring Modulith by Oliver Drotbohm . Designed for managing application modules, it provides new capabilities for code organization, integration testing, and event handling. Let's see what's new in the latest version.
Spring Modulith 1.3 (besides the upgrade to Spring Framework 6.2) introduces nested application modules, enabling modules to be organized within each other. These modules can be hidden from others at the same hierarchical level, allowing for better structural separation of responsibilities. For example, a nested Inventory module has access to the parent module's code but remains invisible to other modules like Order. This feature allows for the creation of more granular and manageable systems.
Integration testing has been significantly improved. Version 1.3 introduces a JUnit Jupiter extension that analyzes project changes and runs only the necessary integration tests, greatly speeding up testing in CI/CD systems. Additionally, the @ApplicationModuleTest annotation now supports explicitly defining the tested module, allowing tests to be located outside the module's package space.
The new Spring Modulith also offers new event handling modes, such as immediate entry deletion or archiving. Archiving preserves event histories for statistical purposes while reducing operational load. Support for headers in external events and dynamic routing key calculation using SpEL expressions has also been added. Integration with Amazon SQS and SNS has been moved to Spring Cloud for AWS, simplifying the project internally. Modulith 1.3 also supports documentation generation, including integrated documents connecting all module artifacts. Full Release Notes are available here.
There is no place to cover all the projects here, so I will share great overview of each feature by Josh Long, Spring Developer Advocate
As you can see, the Spring ecosystem is bustling. But that's not the only "universe" with a lot of interesting developments.
2. JetBrains Updates: Kotlin 2.1, IntelliJ IDEA, Amper... and Advent of Code
"We’ve tackled" topics related to Spring, it’s time to take a step further and look at the second important ecosystem—the loosely connected JetBrains universe, including IDEs, JetBrains, and Amper.
Kotlin 2.1.0
Let’s begin with the latest version of the company’s language. For more details, check out the livestream linked below, which will air later on the day of this release - I’m planning to watch it myself:
Released yesterday, Kotlin 2.1.0 introduces a range of new (currently in preview) language features that enhance code syntax and flexibility. All of the following require enabling specific flags.
For instance, you can now use guard conditions in when expressions with an argument:
fun feedAnimal(animal: Animal) {
when (animal) {
// ...
is Animal.Cat if !animal.mouseHunter -> animal.feedCat()
// ...
}
}
Additionally, non-local break and continue statements are now available. In standard Kotlin, break and continue only work within the nearest loop, which can be limiting in nested structures or when using inline functions with lambdas, such as forEach. The introduction of non-local break and continue allows precise control over program flow, enabling you to exit or skip iterations in specific loops, improving both code readability and predictability.
fun processList(elements: List<Int>): Boolean {
for (element in elements) {
val variable = element.nullableMethod() ?: run {
log.warning("Element is null or invalid, continuing...")
continue
}
if (variable == 0) return true
return true
}
return false
}
Another notable feature is the multi-dollar string interpolation. In standard Kotlin string interpolation, the dollar symbol ($) is used to embed variable values or expressions into strings. However, when you need a literal dollar sign in a string, you have to escape it with a backslash (\), which can reduce code readability.
val price = 150
val message = $$"The cost is $$${price}."
println(message) // Output: The cost is $150.
In the example above, double-dollar ($$) at the beginning of the string indicates that three dollar signs ($$$) are required for interpolation, making it easier to include literal dollar signs without backslashes.
The update also brings improvements to function overloading resolution for generic types and stricter exhaustiveness checks for sealed class when expressions. These enhancements make code more concise and readable while giving developers greater control over application structure and logic.
On the JVM platform, Kotlin 2.1.0 allows generating classes using Java 23 bytecode, unlocking new optimization and compatibility possibilities with the latest Java versions. Nullability annotations with JSpecify have also been improved, raising their severity to errors, which ensures better type safety during Java interoperability. Furthermore, changes to overload handling for unsigned types resolve previous ambiguities, enhancing code consistency and reliability.
Multiplatform projects gain new capabilities as well. Kotlin/Wasm introduces incremental compilation, reducing binary sizes by up to 30% and improving JavaScript interoperability. Kotlin/Native enhances support for iosArm64, improves caching in cinterop, and updates LLVM to version 16.0. Cinterop, which generates bindings between Kotlin and C libraries, now benefits from improved caching, reducing compilation times and boosting performance during integration with C code. In Kotlin/JS, ES2015 arrow functions are now supported, along with properties with non-identifier names, greatly facilitating integration with modern JavaScript environments.
In terms of build tools, Kotlin 2.1.0 includes improved support for Gradle and the Android Gradle Plugin, a stable DSL for compiler options, and a new API for creating Gradle plugins for Kotlin. The update also introduces global options for suppressing compiler warnings and advanced project configuration features, including Swift Export support in Kotlin Multiplatform.
Intellij Idea 2024.3
The IntelliJ IDEA 2024.3 update introduces significant improvements in Kotlin support. The most important change is the recognition of the K2 mode as stable (as we wrote last week), which means full support for the new Kotlin compiler frontend. This opens the door to using modern language features and optimizations in everyday projects. The data flow analysis engine has also been improved, handling variable aliasing better, which reduces the number of false alarms during code inspection.
Among the general new features, the expanded Structure tool window now offers a logical view of the code:
This makes it easier to analyze dependencies between project components, especially in large applications. Additionally, the formatter has been improved to better handle annotation and declaration formatting, increasing code readability. For Kubernetes users, debugging tunnel support has been added, allowing for local debugging of microservices running in the cluster, as well as access to cluster-level logs with filtering and streaming capabilities. These improvements speed up problem diagnosis and simplify working with distributed systems.
IntelliJ IDEA 2024.3 also couldn’t miss new AI-related features that enhance productivity while working with code. New inline contextual suggestions allow direct use of the AI assistant in the editor, simplifying coding and suggesting solutions. Additionally, a new context management interface has been introduced, enabling better management of files and instructions in the project. Developers can now also choose their preferred AI model, including Google Gemini, OpenAI, or local models, providing greater flexibility and customization of the tool for specific project needs.
Full Release Notes you will find there.
Amper 0.5.0
But that’s not all JetBrains has brought us recently.
Amper is an experimental project configuration tool developed by JetBrains, aimed at simplifying the process of building, packaging, and publishing applications, particularly in the context of Kotlin Multiplatform. It uses a declarative YAML format to define configurations while integrating with existing tools like Gradle.
The latest update, Amper 0.5.0, introduces improvements in handling project files and modules, enhancing the user experience when working with multiple modules. Additionally, thanks to new tools in the IDE, users can now manage project configurations more easily. Moreover, integration with Kotlin Symbol Processing 2 (KSP2) allows the use of symbol processors in Amper-based projects, opening up new possibilities for code generation and build task automation. Amper has also been updated to Kotlin 2.0.20, representing a significant step forward in catching up with the rest of the ecosystem.
And finally, let’s get festive.
Starting with the question—who has PTSD seeing this picture?
As the holiday season draws near, Advent of Code is set to kick off. This yearly coding contest sees brave participants vying to complete progressively complex programming challenges... the latter weeks are truly tough (just check that behind the scenes). Trust me, I’m participating for the fifth year in a row.
Just like the previous year, JetBrains, Ksenia Shneyveys and Sebastian Aigner has once again invited the community to solve more tasks in Kotlin, offering their own leaderboards and promising rewards to anyone who completes at least three tasks without using LLM. They have also prepared a ready-to-use repository for anyone who wants a basic structure for solving tasks. If you encounter any difficulties, they will also be broadcasting live streams of task solving in idiomatic Kotlin. You can find more details on their blog.
However, if you’re interested in joining a local leaderboard, I encourage you to participate in one where I’ve competed myself. However, I suspect that my commitments, including writing this newsletter and other responsibilities (one of which is 3.5 years old), will likely mean that I won’t be a tough competitor 🥴
You can use this code 3230435-45a28415 (and input it here), and our active support group you will find here.
Although I’ve learned in recent years that during the Advent of Code, it’s more crucial to be methodical and tenacious, rather than just churning out code mechanically. Just leave the latter to GPT-4 - there is no fun in that.
PS: I will certainly not overthink this year and will be using Kotlin. Enjoy your 6:00 AM wakeups!
Advent of Code is not the only Advent calendar a Java developer should be interested in. The Java Advent Calendar by Olimpiu Pop is an annual initiative by the Java community, running from December 1st to 24th, where a new article related to Java and its ecosystem is published each day.
Every day, experts from around the community share their knowledge and experience, covering topics such as language updates, frameworks, best practices, tools, and programming curiosities.
And this year, you can expect some surprise - nonetheless, it is always worth checking, and I'm doing that each year.
Now, it’s time for the standard Release Radar.
3. Release Radar
Cats-Actors 2.0
Last week, we discussed Akka, so now it's time to show that the Actor model has some alternatives… especially in Scala. But first, a bit of context for those not deeply immersed in the ecosystem.
Cats is a library for Scala designed to provide advanced functional abstractions and tools based on the principles of functional programming. The name "Cats" comes from categories, a key concept in category theory (who would have guessed?), which forms the mathematical foundation of functional programming. If you're curious about the topic, you can learn more about category theory from courses of Bartosz Milewski. This library is often used in projects that focus on clean, declarative code structures, and its versatility has made it one of the key components of the Scala ecosystem.
Cats-Actors is a library based on Cats and Cats-Effect, enabling the creation of actor systems in Scala. It uses the Actor model as a higher-level abstraction for concurrency, making it easier to build highly parallel and fault-tolerant applications.
In the recently released version 2.0.0, significant improvements were introduced, such as integration with typed actors, which enhances type safety and simplifies communication management between actors. Timeout handling in finite state machines (FSM) has been improved, providing more reliable time management in actor processes. The library offers supervision mechanisms, allowing the definition of strategies for handling actor failures, thereby increasing system reliability. State isolation within actors and error handling through supervision form a solid foundation for building fault-tolerant systems…
IMHO, it wouldn’t be the worst investment of time - if we avoid Cargo Cult programming, functional programming can significantly expand the range of solutions available to us as developers.
Micronaut Framework 4.7.0
We’ve already discussed Spring, so it’s time to look at one of its competitors. Among the key features of the latest Micronaut Framework 4.7, announced by Sergio del Amo Caballero, we can highlight improvements to the HTTP client implementation and a new FilterBodyParser API interface, enabling more flexible request body processing. Developers can now also disable property key normalization in @EachProperty annotations, providing greater control over application configuration. Additionally, the display of errors related to circular dependencies has been improved, and more aesthetically pleasing error pages in HTML format have been introduced.
Version 4.7.0 also integrates new modules, such as Micronaut LangChain4J, which simplifies injecting language models directly into Micronaut components (and we’ll return to LangChain4J later in this edition). Another new feature is Micronaut GraalPy, which simplifies exposing Python modules as Java components, increasing interoperability between these languages. In the security domain, the Micronaut Security Cross-Site Request Forgery (CSRF) module has been added, protecting applications from CSRF attacks. Integration with Micronaut Views allows automatic generation of CSRF tokens in forms. The update also brings numerous dependency updates, ensuring better compatibility and application stability.
Quarkus 3.17
We have a hat trick, as the new Quarkus made it just in time!
Quarkus 3.17, announced by Guillaume Smet, has expanded its application monitoring capabilities by introducing OpenTelemetry support in the WebSockets Next extension and OpenTelemetry Simple Processors for tracing and logs. These processors enable faster transmission of telemetry data without batching, minimizing the risk of data loss, particularly for lambda functions and short-lived processes. Additionally, with MicroProfile Telemetry 2.0, automatic JVM and HTTP request metrics are now supported in OpenTelemetry, simplifying comprehensive application monitoring.
In the area of security, a new feature allows defining permissions through CDI bean methods, offering a more flexible and robust alternative to Expression Language. This approach ensures better readability and debuggability of permission logic, utilizing plain Java. For data sources, mechanisms have been introduced to prevent issues with inactive databases—such sources no longer impact health checks and trigger fast failures when inadvertently used, eliminating potential management challenges.
Quarkus has adjusted its locale support to meet the requirements of GraalVM/Mandrel versions >= 24.2, ensuring compatibility with upcoming platform updates. These changes guarantee seamless handling of regional formats (e.g., dates, numbers, languages) in native GraalVM environments. The updates position Quarkus as a leader in performance optimization and readiness for future technological challenges.
Apache Fury 0.9.0
Apache Fury is a data serialization framework utilizing JIT compilation and zero-copy techniques. The latest version Apache Fury 0.9.0 by Shawn Yang introduces significant enhancements for Kotlin support, with optimized serializers and integration with Kotlin's standard library. Additionally, the implementation of UTF-8 string encoding for Java has been optimized, which, according to the developers, is twice as fast as the standard JDK implementation.
Version 0.9.0 also reduces the overhead associated with calculating hashcodes for small strings (up to 16 bytes), adds the ability to treat enums as strings, and includes support for ranges in Scala. Furthermore, compatibility with GraalVM has been improved.
Gradle 8.11
One of the key features of the latest Gradle 8.11 is the optimization of Configuration Cache through parallel loading and saving of entries, speeding up the build process in large projects. Additionally, projects created using gradle init now have Configuration Cache enabled by default, making its adoption easier for users.
Version 8.11 also introduces improvements in error and warning reporting, particularly for the Developer Experience. Java compilation errors are now displayed at the end of the build log, making them easier to identify and resolve. Additionally, problem summaries are generated in HTML format by default, allowing for clearer analysis of encountered issues.
The update also includes support for Clang and GCC tools on Linux arm64 architectures, extending compilation possibilities on these platforms. Moreover, several API enhancements for build authors have been introduced, enabling more efficient and flexible build process definitions.
LangChain4j 0.36
The latest version LangChain4j 0.36.0 by Dmytro Liubarskyi primarily raises the minimum required Java version to 17, allowing the use of modern language features in the library’s API. The API itself has been enriched with a low-level interface that enables precise parameter definitions for Tools, giving developers greater control over the configuration and integration of external components. Additionally, the dependency on Lombok in the langchain4j-core module has been removed, simplifying the compilation process and reducing potential compatibility issues—a problem cited by the team working on the Microprofile AI standard mentioned a few editions ago.
Version 0.36.0 also introduces new integrations, such as support for Cohere as an embedding store. Support for Google AI Gemini as a streaming chat model has also been added, along with similar support for China’s DashScope, a service offered by Alibaba Cloud that provides APIs for integration with large language models and other AI models. Moreover, integration with Mistral as a moderation model simplifies filtering and controlling content generated by applications. Integration with Anthropic models now supports buffering system messages and tools.
Lastly, an interesting tidbit (at least for now).
On November 22, 2024, the company Deno filed a petition with the USPTO to invalidate Oracle’s trademark "JavaScript," a derivative of Java. The allegations include the generic nature of the name, fraud in trademark renewal, and abandonment by Oracle. The case has gained massive community support, including from JavaScript’s creator, Brendan Eich, and could change the way the programming language is perceived in the future. This is a developing, intriguing, and complex story, and I’ll revisit it once the other side responds to provide fair context about the trademark’s history. As you can imagine, it has quite a bit to do with Java 😉
To wrap things up, two CFP invitations
The Call For Papers for GeeCON 2025 has started. It will take place in my Mothership: Krakow, Poland, and topics include JVM, cloud computing, software engineering, and emerging languages. Submissions are open until January 31, 2025.
I love GeeCON and would love to see you there - it's a unique chance to meet live, as I’ll definitely attend the conference.
On the other hand, the CFP for this year’s KotlinConf is ending. If you want your talk to appear at the largest Kotlin conference, don’t miss this opportunity and submit your proposal here by November 30.
BTW: No promises yet, but I’ll try to find a way to inform potential speakers reading this newsletter about upcoming CFPs. I just need to find a reliable source of such information 😃 So if you’re organizing a conference and want to share your CFP, let me know 😃
And next week - the JDK 24 Feature Freeze. I can’t wait to dive into all the announced features
PS: Happy Thanksgiving to readers in the US. I envy you.