The overview of the new JEPs: String Templating, Sequenced Collections, Project Liliput and others - JVM Weekly #17
Today we have two main topics – a slew of new JEPs and announcements from Spring – as the developers discuss how the work on modernizing the framework is going.
1. The Shaun of JEPs: String Templating, Sequenced Collections, Project Liliput, and others
We are fresh from the release of the new JDK, so we are entering a period of increased momentum in publishing new JEPs. A few interesting ones have appeared in recent weeks, which we will now look at.
Less than a month ago, I reported about the email exchanges regarding the Amber project. Now we can see their first results. Both unnamed local variables and Pattern Matching for Records have lived to see their own JEPs in Draft form. Compared to the earlier mailing discussions, which were somewhat chaotic from an outside reader's perspective, those interested can now see a more crystallized, condensed proposal.
A candidate JEP that may interest a broad audience is JEP 431: Sequenced Collections. As the name suggests, it brings a common interface for collections that preserve the order of the elements. The desire for a common abstraction stems from the fact that, at this point each of the collections found in the JDK behaves slightly differently in this matter. The new interface is intended to provide a standardized way of selecting a collection's first and last elements.
void addFirst(E)
void addLast(E)
E getFirst()
E getLast()
E removeFirst()
E removeLast()
The interfaces of individual collections are also to be expanded, and each of the above methods will live to a default implementation. So this is another example of how the mechanisms introduced back in JDK 8 facilitate the evolution of the standard library APIs.
I love the fact that the original JEP included a quote from Kierkegaard
"Life can only be understood backwards; but it must be lived forwards."
Stuart Marks, the creator of JEP, must have a knack for philosophy 😉 And since I also love the Danish man, it made me instantly feel that strange, comforting chill in the heart.
Another JEP currently being worked on extensively is JEP 430: String Templates (Preview). It's surprising how relatively late in its life cycle (the language is, after all, already a bit of a year old on its neck) Java developers decided to make it easier for programmers to work with longer chunks of text. This functionality exists in pretty much every other JVM language. After long years of fine-tuning blocks of text, the next step is to make them more dynamic. The developers propose the following syntax:
String name = "Joan";
String info = STR."My name is \{name}";
assert info.equals("My name is Joan"); // true
In which STR is the so-called template processor
, automatically imported into any Java file.
I highly recommend reading the original JEP. Inside, you will find a fairly thorough comparison of templating syntax (and the string interpolation) in other languages and sensibly laid out arguments for and against the various approaches. Solutions already in place in the JDK are also put on the line. Overall, the whole thing is another example for me of how "obvious" solutions at first glance are not so obvious after all. And it is usually this lesson that for me constitutes the value of reading JEPs.
And finally - Project Liliput, which has been quiet somehow since May, took me by surprise yesterday with a new JEP: 64 bit object headers. The goal of Liliput is to reduce the size of Java object headers in the Hotspot JVM from 128 bits to 64 bits or less. That's because right now, each object, whether small or large, has a fixed overhead of 128 bits in theory and 96 bits in practice (with header compression enabled). Within this space are pointers to the object, its hashcode, and data related to Garbage Collectors or locks. 128-bit does not seem like a significant memory overhead. However, it should be remembered that we are talking about the header, which is added to every single object. In many applications, e.g. when many tiny objects are created (the developers cite machine learning, for example), this overhead becomes very significant, hence the work on Lilliput. The developers have now achieved 64-bit headers at the expense of reducing the possible hashcode complexity and several other optimizations. The JEP mentioned above contains details of exactly which parts have been reduced and what implications the changes may have for the future development of e.g. Valhalla.
Sources
2. Spring is experimenting with Virtual Threads, will be late with modules.
Last week, as part of the JAX London conference, there was a talk on the imminent release of the new Spring - Spring Boot 3 and Spring Framework 6 - a new generation. Unfortunately, the recording is unavailable online, but Infoq shared what the session in question contained.
Certainly, the good news is that both releases' deadlines are to be met, and we can expect the new editions by the end of November, so quite soon. However, it won't be as rich a release as first announced - for it turns out that the long-awaited support for JPMS, the Java module system, won't be ready for release. As the developers admit, it can be expected to appear in later versions. Still, the first edition of Spring Framework 6 focuses specifically on support for Ahead-of-Time and GraalVM compilation, and modules would hinder this process by complicating the so-called "reachability analysis." After all, it should be remembered that unlike new players in the framework market like Quarkus, Helidon, and Micronaut, Spring relies very heavily on the Reflection API. Therefore, supporting GraalVM, which does not support reflection, is much more difficult for them.
Hence the modules have gone down the drain, as the developers make it clear that they are counting on Project Leyden here, which is meant to standardize AoT compilation on the JVM. Since Leyden is part of the JDK, it must take JPMS into account. Until it's relea
sed, however, Spring chooses to focus on Native Images.
Another thing Spring developers are looking at are virtual threads. On Tuesday, Spring's first official statement about their support of Virtual Threads was published. Once again, the framework's long heritage casts a shadow here - the framework has large numbers of synchronized
blocks, which, while not a blocker per se, makes the whole process a bit more complicated. However, Spring developers are aware of this and are analyzing which parts they need to address first, and they are experimenting with the methods recently provided by the JDK. IMHO as a community, we should be happy with this approach. It's good that Spring cares about realistically gaining something from Virtual Threads, and not just ticking off another "revolutionary" feature from the checklist. Again, new players are far more elastic than a long-standing giant.
Overall, this shows that Annotation Processors, on which Micronaut and colleagues are based, has been a big game-changer for the framework space. And there's probably no better way to see how big it is than to build your own. Interested? Then I have something cool for you at the end. Jacek Dubikowski started a series called Build your own framework using an annotation processor describing, nomen omen, the process of creating your own framework from scratch - the kind of hobbyist framework, not something ready to fly into production (Java is not JavaScript). The first article deals with the implementation of Dependency Injection, and takes you step-by-step through the details of such a process, as well as potential problems that may arise along the way. I recommend it - I have always found reverse engineering and "tinkering" to be the best educational tools.