The Rest of the Story: March Edition - JVM Weekly vol. 168
From JDK 26 going GA through JetBrains doing... everything at once seemingly to ClawRunr proving the JVM is ready for the agentic era - March was packed.
This time the material practically wrote itself. JDK 26 shipped, JHipster caught up with Spring Boot 4, Kotlin keeps polishing K2 like it’s a family heirloom, JetBrains reshuffled its product strategy, and the JVM agentic ecosystem quietly got its first serious reference implementation. On top of all that, the community had one of its best months for thoughtful technical discourse — debunking performance myths, formalizing benchmarking standards, and connecting polyglot runtimes. Let’s dive in!
1. March: The Rest of the Story
Just as a reminder - JDK 26 went GA on March 17th - ten JEPs across five categories, and more substance than most non-LTS releases deserve. The infrastructure headline is JEP 516 (Ahead-of-Time Object Caching with Any GC), which extends Project Leyden’s AOT cache to all garbage collectors — including ZGC, which was previously incompatible due to its advanced memory layout. The fix is elegant: instead of directly memory-mapping cached objects in a GC-specific format, they’re now loaded sequentially from a neutral, GC-agnostic representation. JEP 522 squeezes up to 15% more throughput from G1 by reducing synchronization overhead between application and GC threads. And JEP 519 brings HTTP/3 to the built-in HTTP Client API - a long-awaited modernization that brings QUIC-based transport to Java’s networking stack.
On the security front - and this tends to get lost in the JEP noise - JDK 26 delivers a quietly impressive batch of improvements. The headline is Hybrid Public Key Encryption (HPKE) support per RFC 9180, accessible through the familiar Cipher API with a new HPKEParameterSpec class. HPKE combines a KEM, KDF, and AEAD algorithm into a modern encryption scheme that’s already widely used in protocols like TLS ECH and MLS - and Java finally speaks it natively. For now it’s limited to traditional algorithms (X25519 and friends), with PQC variants coming once the IETF draft matures. Alongside HPKE, the jarsigner tool now supports ML-DSA signatures — meaning you can sign JARs with a quantum-resistant algorithm today. Not “in preview,” not “experimental” - actual production jarsigner support. The post-quantum transition isn’t theoretical anymore; it’s in your build pipeline.
As Sean Mullan notes in his traditional JDK security roundup - which remains the single best resource for tracking Java’s security evolution release by release - these changes collectively push Java’s crypto stack further toward post-quantum readiness while cleaning out the legacy cruft that’s been accumulating for decades.
For teams still on JDK 21: Oracle’s permissive NFTC licensing for JDK 21 ends in September 2026. Migration planning should be well underway.
Ronald Dehuysser and the team at JobRunr launched ClawRunr (also known as JavaClaw) - an open-source AI agent runtime built on JDK 25, Spring Boot 4, Spring AI, and JobRunr. It’s essentially a Java port of OpenClaw - the Node.js personal AI assistant we discussed back in the OpenClaw/Peter Steinberger edition.
Let me start with strong statement - this is one of my favourite Duke personas ever.
What makes ClawRunr architecturally interesting: agents can self-schedule cron jobs, one-shot tasks, and recurring work through tool calls, with JobRunr persisting everything across restarts. Skills are loaded at runtime via SKILL.md files dropped into a workspace directory - no recompilation, no redeployment. Supports OpenAI, Anthropic, and Ollama out of the box - to run entirely on your hardware. The stack reads like a Spring Boot 4 showcase application - which, strategically, may be exactly the point.
Combined with SkillsJars (Maven Central as a package manager for AI agent skills, from last month’s ROTS) and the Open Liberty MCP feature (more on that below), the JVM agentic ecosystem is coalescing faster than I expected. Someone should probably write some overview of this trend... 😉
JetBrains made two significant strategic moves this month that read as a single coherent narrative. First: core JavaScript and TypeScript support is now free in IntelliJ IDEA. Historically, robust web development was a primary differentiator for the paid Ultimate Edition, often forcing JVM developers to context-switch between IntelliJ for backend and VS Code for frontend. This move directly targets that friction = and acknowledges that the modern developer persona is rarely confined to a single language.
Second: Code With Me enters maintenance mode starting with IDE version 2025.1, with full decommission by 2026.3. JetBrains is transitioning from the plugin’s peer-to-peer relay system to a thin-client model powered by JetBrains Gateway and the Remote Development protocol. For JVM engineers, this means moving toward a headless backend execution model — the JetBrains Client handles UI, the heavy lifting happens server-side.
Together, these moves signal JetBrains consolidating around two pillars: IntelliJ as the unified polyglot hub (countering VS Code), and Gateway as the enterprise-grade remote development infrastructure. The collaborative plugin era is over; the protocol-driven era begins.
However, that’s not all from JetBrains, they had quite a busy month seemingly.
JetBrains introduced new inspections in IntelliJ IDEA targeting the intersection of Kotlin Coroutines and JDK 21 Virtual Threads - a pain point that’s been growing since Loom went GA. The inspections identify risky patterns like making blocking calls within a coroutine scope without the appropriate Dispatcher. This is particularly critical for Spring Boot developers leveraging Virtual Threads: inadvertently blocking a carrier thread or “pinning” it can cause performance regressions that are devilishly hard to debug at runtime.
Managing dual concurrency abstractions - Coroutines and Virtual Threads - within a single codebase remains one of the trickiest challenges in modern JVM development. These guardrails won’t solve the fundamental design tension, but they’ll catch the most common mistakes before they make it to production.
But the crème de la crème dropped just yesterday. JetBrains announced Central - and this one reframes everything above into a single strategic picture. Central is positioned as “the control and execution plane for agent-driven software production” — a layer that connects IDEs, CLI tools, AI agents (not just Junie, but also Claude Agent, Codex, Gemini CLI, or custom-built solutions), and infrastructure into a unified system with governance, cost attribution, and observability.
Think of it as: free JS/TS support gets more developers into IntelliJ, Gateway provides the headless execution model, Air from two weeks ago coordinates human-agent workflows - and Central sits on top as the enterprise control plane that makes it all manageable at scale.
The reasoning behind Central is straightforward if you’ve been paying attention to how AI is actually used in engineering organizations today: most developers already use AI at work, and coding agent adoption is accelerating fast - but the impact remains overwhelmingly limited to individual productivity. Almost nobody has AI meaningfully integrated across the entire software development lifecycle, from code review through the release pipeline. The gap between “individual developer productivity” and “organizational software delivery” is precisely where Central aims to land - with policy enforcement, identity management, semantic context across repositories, and intelligent routing to the right models for the right tasks.
EAP launches Q2 2026 with design partners. Whether this becomes the “Kubernetes for AI agents” or just another enterprise dashboard remains to be seen - but the ambition is unmistakable. JetBrains isn’t just making tools anymore. They’re building the operating system for how software gets produced in the agentic era.
Jonathan Vogel post “Java Is Fast. Your Code Might Not Be” - based on his DevNexus talk - sparked one of those community discussions that ends up being as valuable as the original article. The premise is absolutely right: application-level inefficiencies can bottleneck even the fastest runtime, and Vogel’s demo numbers are genuinely impressive (from 1,198ms down to 239ms, heap from 1GB to 139MB, same app, same JDK). But the Hacker News thread turned into a fascinating conversation about which of the cited anti-patterns still actually matter in 2026 - and it (once again) inadvertently exposed how much the JVM has changed under the hood while our collective intuition hasn’t always kept up. The StringBuilder pattern, for instance, is one many of us learned early in our careers, and it made perfect sense at the time. But since JEP 280 in Java 9, the compiler leverages invokedynamic and StringConcatFactory to optimize concatenation strategies dynamically - which means the runtime has been quietly handling this for us for years now.
The ensuing discussion turned into a genuinely useful conversation about where performance gains actually live in modern Java. The real culprits today - excessive object allocation, deep abstraction layers in popular frameworks, using Streams on hot paths where a simple loop would suffice, the lack of “mechanical sympathy” regarding CPU caches - got a thorough airing.
The consensus landed in a good place: the “Java is slow” myth is dead, but it’s been replaced by a subtler truth that profiling is a mandatory discipline, not a nice-to-have. Tools like JFR and async-profiler are where the signal is, and the JVM has gotten so good at optimizing the basics that our energy is better spent elsewhere. Honestly, the whole episode was a healthy reminder for all of us - myself included - that it’s worth periodically revisiting our performance assumptions against the current state of the runtime. The JVM of 2026 is a very different beast than the one we formed our mental models on.
Thanks Jonathan, can’t wait for the followup articles!
On a related note, Quarkus is formalizing a benchmarking methodology that moves beyond vanity metrics. Instead of raw process startup time, they’re measuring “Time to First Request” and Resident Set Size (RSS) - the metrics that actually matter for Kubernetes deployment density. In “Peanut” configurations (0.5 vCPU, 256MB RAM), Quarkus demonstrates sub-100ms response times and ~20MB RSS footprints in native mode. The testing environment uses Hyperfoil for load generation with strict hardware isolation via taskset and cgroups for deterministic results.
Even better: the new quarkus-benchmarks repository now provides transparent, reproducible comparisons against .NET minimal APIs and Go - not just internal JVM-versus-JVM battles. Java proving parity on startup and memory with .NET and Go in container-constrained environments is the kind of data we’ve been waiting for.
Josh Long hosted discussion with Cay Horstmann - the author of the definitive Core Java series - durign the Java One. For anyone who learned Java from Horstmann’s textbooks (and that’s... most of us - not many technical books has 12 Editions(!)), it could be a really interesting listen.
Pi4J, the Java IO library for Raspberry Pi, officially joined the Commonhaus Foundation. Frank Delporte (Java Champion, technical writer at Azul) described the move as ensuring the project survives beyond its current team. Pi4J follows Micronaut’s January announcement of its own application to Commonhaus. The consolidation of JVM open source under a neutral, sustainable foundation continues - and that’s unambiguously good news for everyone who depends on these libraries. Pi4J V4.0 also shipped on February 20th.
The beta of Open Liberty 26.0.0.3 ships with updates to Model Context Protocol integration for Jakarta EE applications. New ContentEncoder and ToolResponseEncoder interfaces for finer control over encoded responses, plus session-based request IDs via a RequestID record. This makes Open Liberty one of the first enterprise Java application servers with first-party MCP support. Combined with the Jakarta Agentic AI initiative under the Eclipse Foundation, enterprise Java is taking the agent story seriously - and not just through Spring AI. The specification-driven path is advancing in parallel.
Did I mentioned somebody should write an article about it?
A developer retrospective on building a Kotlin CLI tool with GraalVM Native Image versus standard OpenJDK 21 highlighted sharp trade-offs. Using a KMP-compatible stack (Clikt, Ktor, Koin), the project achieved 10ms startup for the native binary versus 800ms on the JVM - an 80x delta on Apple Silicon M3.
The reflection metadata configuration remains the primary friction point. The community consensus: run the GraalVM tracing agent against a JUnit suite to exercise reflection paths and auto-generate reachability metadata. But critics raised a pragmatic point - for tools dependent on high-latency LLM APIs, JVM startup overhead is often negligible compared to network I/O. And since the chosen libraries are fully KMP-compatible, Kotlin/Native may now be a more efficient path for CLI tools, bypassing GraalVM’s configuration hurdles while maintaining similar performance profiles. Food for thought.
JetBrains announced Kotlin’s participation in GSoC 2026, with projects centered on the K2 compiler architecture, Kotlin Multiplatform tooling, and Kotlin/Wasm backend optimizations. The emphasis on K2 Intermediate Representation for advanced compiler plugins and KSP API refinement signals continued investment in post-KAPT build performance. Projects are structured in 175-hour and 350-hour tiers — a mix of library parity work within kotlinx and deep compiler engineering.
Two new projects push the JVM toward high-performance polyglot execution. swc4j compiles TypeScript directly to JVM bytecode using ASM 9.7, leveraging the Rust-based SWC parser via JNI. It maps TypeScript primitives directly to Java types (number → double), bypassing the GraalJS Polyglot API entirely - designed for environments where JIT-warmup delays and engine memory footprints are unacceptable.
Meanwhile, WebAssembly4J provides a unified API across Wasm runtimes (Wasmtime, WAMR, Chicory) with dual integration paths: JNI for Java 8/11 compatibility and Project Panama (FFM API) for Java 22+. For engineers who’ve been watching the Wasm-on-JVM space: the “black box” script engine era is giving way to more transparent, low-latency execution models where TypeScript and Wasm become first-class JVM citizens.
Finally, informational JEP draft: JDK Source Structure formalizes the internal architecture of the OpenJDK source repository. While it introduces no new features, it codifies the src/$MODULE hierarchy - share for platform-independent logic, strict OS/CPU-specific isolation - as the “single source of truth” for contributors. If you’ve ever wondered where to look in the jdk/jdk Git repo, this is now your definitive map.
When it will be moved from the draft, you can be sure I will get back to it.
2. Release Radar
Kotlin 2.3.20
Kotlin keeps polishing. Kotlin 2.3.20 marks a significant stabilization of the K2 compiler ecosystem with some language features that actually matter in daily work. The headline: name-based destructuring for data classes - extracting properties via explicit identifiers rather than positional indices. If you’ve ever refactored a data class and introduced a subtle bug because the second and third properties were both String - this is for you. Consider:
data class User(val name: String, val email: String, val role: String)
// Before 2.3.20 — positional. Swap email and role in the data class
// and this silently breaks:
val (name, email, role) = user
// With name-based destructuring — resilient to reordering:
val (name = name, role = role, email = email) = userAlso new: guarded when expressions - essentially if-predicates inside pattern matching branches, which eliminates the awkward nested-if-inside-when pattern that made complex matching feel clunky:
when (val result = fetchData()) {
is Success if result.data.isNotEmpty() -> process(result.data)
is Success -> handleEmpty()
is Error if result.isRetryable() -> retry()
is Error -> fail(result.cause)
}Previously you’d either nest an if inside the is Success branch or split it into separate when blocks - neither of which read well. This syntax makes the intent immediately clear: the guard is part of the pattern, not an afterthought.
Beyond language features: experimental non-local break and continue in inline lambdas (a long-standing community request), and - crucially - JFR events for compiler phases, providing much-needed observability into build performance. K2-native incremental compilation is now the default for multi-module projects. The PSI preparation for the transition from context receivers to context parameters is underway. With full support for JDK 23 and Gradle 8.10, the ecosystem remains current.
The most impactful change for K2 adopters? The synchronization of the IDE analysis engine with the compiler backend should eliminate those “red code” inconsistencies that have plagued early adoption. If you’ve been holding off on K2 - this release is your signal to try again.
Staying in the Kotlin world: JetBrains announced direct support for Swift Package Manager dependencies in Kotlin Multiplatform. This removes one of the final significant hurdles to KMP adoption in iOS-heavy environments - CocoaPods integration has been a persistent source of friction, and the ability to consume Swift-only libraries directly through the KMP toolchain is a genuine quality-of-life improvement. The community reaction has been overwhelmingly positive. The beginning of the end for legacy CocoaPods workarounds? We can hope.
IntelliJ IDEA 2026.1
I hope you are not tired with JetBrains narrative for this month - IntelliJ IDEA 2026.1 shipped yesterday, as announced by 👓 Anton Arhipov together with 👩🏻💻 Marit van Dijk , Marco Behler , and Siva Prasad Reddy K in a 1-hour video walkthrough full of demos.
This release is where all the strategic moves we discussed above materialize into something you can actually download. The headline is the Agent Client Protocol (ACP) Registry - browse and install AI agents in one click.
Not just Junie and Claude Agent anymore: Codex, Cursor, GitHub Copilot, and any ACP-compatible agent now work inside IntelliJ natively. The Git worktrees integration is designed explicitly for agent workflows: work in one branch yourself, hand another off to an agent, keep moving. Agents can even query and modify your database sources directly. This is JetBrains Central’s vision, but at the IDE level - the IDE as an open platform for agentic development, not a walled garden.
For the JVM crowd specifically: first-class Java 26 and Kotlin 2.3.20 support from day one (as is tradition). Spring runtime insight lets you inspect injected beans, endpoint security, and property values without pausing execution - a feature that will save Spring Boot developers an embarrassing amount of time they currently spend on debug logging. Kotlin-aware JPA detects and fixes pitfalls like using data class and val fields on Jakarta Persistence entities - problems that silently corrupt your persistence layer because JPA was designed for Java’s mutability model, not Kotlin’s.
The polyglot story continues: C/C++ support via the CLion plugin (for teams mixing JVM with native code), JavaScript and TypeScript now free without an Ultimate subscription (what we already mentioned earlier), and native Dev Container workflows that let you open containerized projects as if they were local. Dependency sources are now auto-downloaded in the background - you always have full context for debugging and navigation.
This is, honestly, one of the most cohesive IntelliJ releases in a while. Every feature connects back to the same thesis: the IDE is becoming the integration point for a multi-agent, multi-language development system. Whether you buy the full JetBrains Central vision or not, the individual pieces are already making daily development measurably better.
What’s New page | What’s Fixed
JHipster 9.0.0
JHipster 9.0.0 reached GA after three beta releases. The headline: alignment with Spring Boot 4.0, cascading into Jakarta EE 10 and the modern JVM stack. JDK minimum bumped from 17 to 21, Node.js from 20 to 22. Frontend refresh: React 19 with react-bootstrap, Angular 21 with zoneless mode and signals, Vue with Bootstrap 5.
But for me, GraalVM native image support is even more interesting addition for cloud-native teams. Additionally, the entire generator codebase has been rewritten in TypeScript. So for JHipster 8.x teams, this isn’t a gentle bump - the new version is huge.
LibericaJDK 26
BellSoft shipped Liberica JDK 26. Of the total 2,825 fixes (2,665 OpenJDK + 160 JavaFX), BellSoft contributed 9. Business as usual from one of the more reliable OpenJDK distributors.
JobRunr 8.5.0
JobRunr 8.5.0 improves startup performance by replacing individual SQL migration queries with a single batch query - a change that sounds trivial but makes a real difference in environments with dozens of migrations stacking up on cold start. Also fixes an AccessControlException when calling ForkJoinPool.commonPool() with the deprecated SecurityManager - a classic “Java archaeology” bug that’s becoming increasingly common as the ecosystem moves away from Security Manager while legacy configurations linger.
Worth noting in the broader context: JobRunr is quietly becoming more than just a background job library - with ClawRunr built on top (see above), it’s positioning itself as foundational infrastructure for the JVM agentic stack.
I also working on some JobRunr based solution - I will share some details soon 🤞
Apache Solr 10
Apache Solr 10 is the first major release since the 9.x series - and this time the changes run deep. Under the hood sits Lucene 10.3, with the minimum raised to Java 21 (SolrJ still works on 17). The biggest story is, of course, vector search: Solr 10 introduces support for scalar and binary quantized dense vectors, significantly reducing memory usage and improving vector search performance. But the real bombshell is the cuVS-Lucene integration - a pluggable codec enabling GPU acceleration for vector operations using the CAGRA algorithm, designed specifically for massive GPU parallelism.
This is exactly the integration NVIDIA talked about at GTC (and JavaOne), citing a 6x end-to-end speedup for index building in Solr and 40x in Lucene itself - and the Java API for cuVS uses Project Panama (FFM API), which closes the loop with the rest of the JDK 21+ ecosystem.
3. GitHub All-Stars
Floci - Native AWS Emulation for Java Testing
Floci is a lightweight, open-source alternative to LocalStack, specifically optimized for Java ecosystems. Unlike containerized emulators, Floci is natively compiled — drastically reducing memory overhead and eliminating JVM warmup times in ephemeral CI/CD environments. Currently supports S3, SQS, and DynamoDB, with seamless Spring Boot, Quarkus, and Micronaut integration. The community is particularly interested in potential Quarkus DevService integration.
For JVM developers tired of LocalStack’s resource demands: “instant-on” readiness without the container overhead.
Savant - Explicit Target Control Over Plugin Magic
Savant is a new Java build system that takes a contrarian stance: no plugin-injected build targets. Plugins function as simple objects in a Groovy DSL - you call java.compile() directly instead of relying on hidden lifecycle side effects.
Despite the focus on transparency and JDK 17+ compatibility, the community response has been skeptical: documentation inconsistencies (C# examples in a Java build tool?), and the question of why not use Mill, Amper, or bld instead. The manual configuration burden may be prohibitively high.
Worth watching, but approach with caution.
KAP - Kotlin Applicative Parallelism
KAP applies Haskell’s Applicative Functor pattern to Kotlin Coroutines - a library for declaratively expressing parallel-then-sequential orchestration. The code shape is the dependency graph: applicative phases run in parallel, monadic phases wait for context. Comes with timeoutRace, retry with Schedule, circuit breakers, and Arrow integration. 906 tests, 119 JMH benchmarks, Kotlin Multiplatform support.
You don’t need to know Haskell to use it - but if you do, you’ll feel right at home.
Jar-Analyzer - Bytecode Analysis Engine
Jar-Analyzer is a bytecode analysis and visualization tool for Java archives. Useful for security auditing, dependency analysis, and understanding complex class hierarchies in third-party JARs. If you’ve ever wanted to look inside a JAR beyond what javap gives you -this is your tool.
PS: This is Asian software - do not expect letters everywehere. Maybe some LLM would be able to do the port/translation.
JavaDesugarer9To8 - Backporting Modern Java
JavaDesugarer9To8 does exactly what the name says: transforms Java 9+ bytecode back to Java 8 compatible bytecode. Niche, but useful for teams stuck on Java 8 runtimes that want to use libraries compiled against newer JDKs. The Android ecosystem has been doing this for years - nice to see it available for server-side use cases too.
However, I recommend to use that with cautious 😊
PS: The full KotlinConf’26 schedule is live - time to start planning! @Jake Wharton on “Talking to Terminals,” Josh Long on “Bootiful Kotlin,” and a talk on enterprise-ready AI agents with Koog from JetBrains. I’ll be there as a media partner - come say hi if you’re attending!
PS2: Yet another picture from “JVM Weekly in strange places” family: Polish classic mountain cottage














