The new Long Term Support JDK version was released as GA on September 19th. It’s been 2 years since the previous LTS version, JDK 17, was released.
With the current approach for LTS versions, a new one will be released every 2 years, with a 6-month cadence for regular versions.
But, at this point, we could be wondering…
Well, it’s “a company's offer to provide services and guarantees for their certified Java implementation, that may or may not be built from an OpenJDK update fork.” quoting Nicolai Parlog from Oracle.
So we rely on the vendor who is providing the Java binary that we use and its particular definition of LTS. Different vendors have different roadmaps and support ranges. LTS versions are usually supported for 8 years, for example, Oracle and Azul are committed until 2031. There are alternatives, for example, Azul has MTS (Medium Term Support) versions.
During the LTS support term bug fixes and vulnerabilities will be ported to that version. For other JDK versions, this process only lasts 6 months.
So, if we use non-LTS versions in production, to be safe we need to update the JDK version every 6 months, running the risk of having deprecated or removed functionalities. LTS is definitely the version to use in production.
Lots of bugs and CVEs are fixed, but also great new production-ready features. I’ll highlight some of them:
- JEP413 - Code snippets in Java API documentation
- JEP431 - Sequenced Collections
- JEP440 - Record Patterns
- JEP441 - Pattern Matching for Switch
- JEP444 - Virtual Threads
- JEP451 - Prepare to Disallow the Dynamic Loading of agents
This new feature allows adding code inside the documentation that will be included in the Java Docs, both from inline code or from external files. It accepts markup tags like @highlight or @replace.
Collections in Java have always lacked an ordered approach. But now new interfaces `SequencedCollection, SequencedSet, SequencedMap` are filling this gap by adding consistent methods across the collections:
addFirst, addLast, getFirst, getLast, removeFirst, removeLast.
Another problem with collections has been trying to get the elements in a reversed order, but with the new
reversed method we have a consistent and effective way of getting them.
This has also been retrofitted to current interfaces:
List, SortedSet, LinkedHashSet, Deque, SortedMap, and LinkedHashMap.
Before Java 21:
With the new sequenced collections, we can do the same thing using simpler methods:
We can use a type pattern to test whether a value is an instance of a record class and extract the component values. For example, with a record Point, you can extract the x and y values.
Before Java 21
With Java 21
The power of pattern matching is expanded to Switch statements to reduce boilerplate code and improve readability.
Before JDK 21
In Java 21, we can write a similar expression with a record pattern as follows:
This is a great feature for JDK 21. Until now every thread that was created had a direct link with a platform or OS thread. Considering the limited availability of those threads it became hard to handle a high magnitude of concurrency.
Virtual threads are a concept that allows having millions of “threads” mapping several virtual threads to one platform or OS thread. With virtual threads, the blocking calls to I/O will be suspended and the thread will be used for another process, just expecting the call to finish eventually.
Basically, the physical threads are shared among virtual threads, allowing hardware utilization to be close to optimal with a high level of concurrency. As a result, it will allow higher throughput, while the application remains harmonious with the multithreaded design of the Java Platform and its tooling.
Agents have been used mainly to allow tools and profiles to instrument classes, and we can find several of them to get observability for the JVM. Basically, agents are components that can alter the code of an application while it is running.
But, it can also be a back door used by agents to alter the normal behavior of an application, without even asking for permission.
In JDK 21, the dynamic loading of agents is allowed but the JVM issues a warning when it occurs.
In order to allow tools to dynamically load agents without showing warnings, the
-XX:+EnableDynamicAgentLoading option must be added on the command line. And this will be the only way in the future to allow Agents.
This new JDK 21 will definitely introduce new features that allow the code to be cleaner more secure and efficient, especially considering concurrency.
With code snippets, we can improve the readability of code examples in the Java API definition. Pattern matching in records and switches will improve consistency by using conventions and making the code more identifiable. Sequenced collections will allow us to have clearer and more intentional code with consistent methods across all collections to obtain the first and last elements and an efficient way of reversing the elements. Virtual threads will boost our application's asynchronous performance making it more efficient. And finally disallowing dynamic agent loading will make the application more secure making it explicit to load agents.
It’s important to consider moving to the latest/closest LTS, even if its features don't excite you in order to have more stable, secure, and efficient software. Upgrading to the JDK 21 LTS for your production code will lock in support for the next 8 years.