There is more in JDK 20 than JEPs themselves. - JVM Weekly vol. 38
Today's topic could only be THE ONE - the release of JDK 20. We will go through what the new release carries but also does not bring.
1. JDK 20 has been released. What kind of JEPs does it contain?
Yeah! At the beginning of the week, we had the release of the new Java. On the one hand - a big event, on the other hand, we have already written so much about it that I have the impression that the very fact of the release is a de facto formality.
When the previous Java consisted mainly of Preview Features, I'll admit that there was something fascinating about it. After all, it was JDK 19 that gave us a glimpse into the future of how the platform would evolve in the coming years and a taste of the results of some long-awaited projects. I have to admit, however, that it's hard for me to summon up similar enthusiasm for JDK 20. Once again, we're dealing with a bunch of Previews, but these are basically minor iterations (with exceptions about which in a moment) of already existing APIs. It's apparent that all the big stuff is waiting for JDK 21, which we recently wrote about.
So the final list of new features in JDK 20 is as follows:
As you can see, completely new things are in short supply. However, the very fact that APIs in the preview version undergo changes is something positive, and such additions in the Foreign Function & Memory API are quite nice - you can read about them, for example, at Per Minborg, who published the text Java 20: A Sneak Peek on the Panama FFM API (Second Preview). On the other hand, the new version of the Vector API, on the other hand, is so "revolutionary" that the JDK developers themselves forgot to add it to the list in the first version - it contains no new changes. Carrying on, if you are curious about the details of the changes in the proposals for new records and pattern matching, I have already written about Record Patterns (Second Preview) and Pattern Matching for switch (Fourth Preview) in one of the previous editions. The situation is similar for the new iterations of Loom-related JEPs - Virtual Threads (Second Preview) and Structured Concurrency (Second Incubator), which I also had a chance to describe. I'm not doing it here again, cause the new features are really rather cosmetic.
To end on a positive note, however, mentioned 437: Structured Concurrency (Second Incubator) has seen one change connected to the most interesting addition introduced in JDK 20 - support for Scope Values. We will deal with these now.
About Scope Locals
The need for local values is due to the changes made to the JVM for Loom. Due to the fact that Loom is based on very lightweight threads (so that it becomes possible to create an essentially unlimited number of them), we have to be very careful about the size of the structures created for each thread.
The popular Thread Locals (variables pinned to a thread) have been a stone in the shoe of virtual thread developers from the beginning. The solution to the problem are mentioned Scope Values - effectively final, non-mutable local variables that can be safely shared between threads as needed, reducing the amount of memory required. Each child thread has access to the full context of its parent. The idea of accomplishing this task was stolen from Common Lisp and its "special variables."
You can think of Scope Values as invisible parameters that are passed to each method. They have the ability to assign a value to a local variable only for a specific scope - when it ends, the values of the variables will be automatically restored. This behavior allows, for example, to cover the values of x and y, in any of the "children", without affecting all other threads using them.
The source code from JEP illustrates this quite well:
final static ScopedValue<...> x = new ScopedValue<>();
final static ScopedValue<...> y = new ScopedValue<>();
{
ScopedValue.where(x, expr1)
.where(y, expr2)
.run(() -> ... code that uses x.get() and y.get() ...);
}
As you can see, the syntax is a bit like the all-too-familiar "atomics" on steroids. The x and y values can be passed from the "parent" thread to the "child" thread. The run() method, in turn, "binds" in this case x and y to the values expr1 and expr2. When the run() method is executed, any calls to x.get() and y.get() return them. When it is exited, the values revert to the previous versions inherited from the parent.
Of course, as is the case with Loom, the syntax can still change many times (especially since we are dealing with nothing but incubation yet).
Sources
2. There is more in JDK than JEPs themselves - what does the community write about in the context of JDK 20?
Reading the first section of this edition, one might come to the conclusion that there's really nothing interesting about this new Java. That's not quite true, because each new release, in addition to the JEPs themselves, usually brings a lot of smaller improvements under the hood. Each time, too, there is a group of heroes without capes who bring the good news and talk about all those extra things that will probably never break through strongly into the mass consciousness.
In fact, the most interesting of the texts accompanying the release of the new JDK was written by Nicolai Parlog - Developer Advocate Java at Oracle - who breaks down the JDK 20 for us in a very cross-cutting manner. His text with the rather perverse title Java 20 🥱 takes us by the hand through, among other things, changes in hash functions, news related to JFR and JMX, or support for Unicode 15.0. There are really quite a few such smaller additions, so I suggest taking a peek at the whole thing even if I have already discouraged you from diving deep into JDK 20 by presenting the "big" features. .
A staple part of every new Java release is Thomas Schatzel's text on changes to Garbage Collectors, and JDK 20 is no different. From the JDK 20 G1/Parallel/Serial GC changes you will learn that while there were no noteworthy changes to Serial GC, in Parallel GC support for Full GC was improved by worker threads handling objects crossing their local compaction regions, reducing Full GC pause times by 20% in selected cases. And in G1 GC, the prediction of the size of the young generation has been improved. This reduces pause time overruns and allows the use of more regions of the young generation for a single GC pass, resulting in an aggregate reduction.
The JDK 20 release includes several security enhancements, as Sean Mullan hastens to report in JDK 20 Security Enhancements, another offshoot of his regularly published series. The new JDKs improve the default security features of the Java platform, enhance the performance of the Crypto module and add new JFR events for security monitoring. Sean also stresses the importance of the fact that new constructors have been added to the InvalidParameterException
exception API, allowing its users to specify the cause of an Exception. Quite a lot has been also added to the list of Java encryption algorithms, including new entries, improvements, and deprecations as well.
The last important new feature is the introduction of new system and security properties that control which classes are allowed to reconstruct objects from JNDI/LDAP and JNDI/RMI contexts. It is worth noting that while these properties are related to the broader concept of security, they do not directly belong to the area of Java security libraries.
Sources
3. Docker movement strikes fear into Open-Source community
And finally, a topic very loosely related to Java, but given how much space has been related strictly to the JDK today, I found it interesting enough to share.
Docker has gone from being a pet peeve of the developer community to gaining quite a bit of disrepute in recent years with a series of several controversial decisions (which in a nutshell can be summarized as "Money would want for the job, nasty capitalists"). Last week, in turn, another one was added to the already existing pile. This is because the company sent an email to all Docker Hub users who had created an "organization", informing them that the company was dropping their Free Team plan and that the accounts that were not migrated would be deleted. The message was delivered in a low-key emphatic manner, with no attempt to explain what would happen to the existing resources in the repository e.g. images,. Unsurprisingly, the decision to end its Free Team subscription has caused alarm in the open-source community.
Docker wrote a reassuring post, admitting that the method of communication was "terrible." In an explanation, the company explains that the outdated Free Team plan has been replaced by a Docker-Sponsored Open Source program, and no images will be removed, the milk has already been spilled. The whole situation will make OSS projects think twice about choosing their main repository for a long time.
By the way, I decided to check which JVM-related projects are classified as Sponsored OSS. It turns out that there are some. This category includes, among others, Jenkins or OpenWhisk. On the other hand, I was somewhat surprised to find that a Debian Liberica SDK, being an image with more than 5 million downloads, is neither an official image nor even a verified publisher. This is all the more amusing because BellSoft are the developers of Alpaquita Linux, an operating system tailor-made just for Java containerization, released last year.
And while we're on the subject of containers, as a seal fanatic (one of mine has an account on Instagram...) I'll mention that we've recently been testing Podman from RedHat, an alternative to Docker with the most adorable logo in the industry, and I have to say that so far it's performing really well. I especially like their desktop application, which is not that different from Docker Desktop, and probably has even better Kubernetes support. With the whole Docker affair, by the way, I found out that they also have their own image repository.
Yay, go Lisp! Guilty as charged, M'Lud.