Java developers, nowadays, are spoiled with a new release every 6 months, Java 13 being the second release this year. In this blog post, I’m assuming that you’re somewhat familiar with updates that have been shipped with previous Java versions. If not, let me know and maybe I’ll cover those as well in a separate post.
So, what’s happening in Java 13?
First time when I saw this term, I was actually intrigued so I looked it up on the OpenJDK website and this is what I found:
A preview language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent. It is available in a JDK feature release to provoke developer feedback based on real world use; this may lead to it becoming permanent in a future Java SE Platform
In other words, a preview feature is not meant to be used in production and its primary goal is to actually get feedback from the developers and improve it before it makes its way to a permanent feature.
Switch Expressions have been actually introduced in Java 12 but it hasn’t been yet finalized so even in Java 13 it is declared as a preview feature. Just a quick reminder on how a Switch Expression looks like:
Java 12 Switch Expressions
Pretty straightforward, huh? “Switch” can now be used as an expression and not just as a statement. You can assign the result of this expression to a variable, play out with the cases ( like chaining them ) and most importantly, every switch case is represented by a “lambda” expression ( it’s not actually a functional interface but it looks like one ).
Let’s now have a look over what has been changed in Java 13:
Java 13 Switch Expressions
This feature is going to be loved by so many developers who deal with building complex Strings in their code. I think almost every java dev has encountered code similar to the one below at least a couple of times in his career:
Java 12 Inline JSON
There are a couple of issues which clog the readability of this JSON. All quotes need to be escaped which makes it a very labor-intensive job, especially when you need to copy this piece of text from a different source. Next, we have end-line characters which reduce even more the visibility of the end result. There is one thing that we can do to improve the readability from this perspective:
Java 12 Multi-line JSON
This actually improves a lot the readability from the new line perspective but it’s still very hard to ignore all those escaped characters and extra quotes. Java 13 comes to our rescue with text blocks:
Java 13 Text Blocks
This feature has actually improved a lot the readability of our JSON. We can clearly distinguish the new lines, there is no need to escape the quotes and the best part of it, we can just copy any text to our file and there will be no need for escaping! All that you need to do is to prefix your text with 3 quotes ( “”” ) and then end with using the same structure.
Java 13 text blocks are the first step to creating template literals more easily by using a new API that has been introduced to the String class: .formatted(Object… args)
We can actually use our string literal as a template and dynamically replace the values, everything done using text blocks and the new API on the String class.
The API changes usually are the most popular since that is something you can clearly work with. Platform updates, otherwise, are not something that you can experience first hand but it is good to keep an eye on them because it will help you understand why something works in a specific way.
Dynamic CDS Archive
CDS or Class Data Sharing is a feature added in Java 5 which can be used mainly for decreasing start-up time and memory footprint of applications while running them in different JVM instances. How does it work? By passing certain arguments, the JVM will create an “archive” of a set of classes which then can be loaded to another JVM. When we load this archive to another JVM instance we’re actually bypassing a lot of steps like loading the classes, parsing and verifying the bytecode so the start-up time will be increased drastically. At first, this feature was only capable to archive classes loaded by the System Classloader but starting with Java 10, the functionality has been extended in such a manner that it can also archive classes loaded by the Application Classloader.
Java 10: CDS – creating the archive
There are a couple of things going on in here:
- The first 2 arguments are used for telling the JVM that we want to use the Application CDS feature and dump the result in an archive;
- hello.lst contains a list of all the application classes that we want to include in the archive;
- hello.jsa the name of the resulting archive;
- the rest is well known;
Now when it comes to loading that specific archive:
Java 10: CDS – loading the archive
It is pretty straightforward:
- firstly, we specify that we want to use the AppCDS feature;
- then we pass the name of the archive that we want to load;
- the rest is well known;
As you’ve probably guessed the trickiest part of this flow is to create the hello.lst file which contains the list of the classes that you want to be included in an archive. For a single class application it’s relatively easy but for enterprise applications that can be quite cumbersome.
The solution comes from Java 13:
Java 13: CDS – creating the archive
Now, instead of passing all those long arguments we can simply state that we want to create an archive with all the application classes loaded when exiting the application: simply and efficient. No need for manually creating the .lst file, no need for passing complex JVM arguments.
To simply load the archive at startup we can use the following command:
Java 13: CDS – using the archive
So, when should you use this feature? Typically, we don’t really care how fast our application starts up ( as long it is in an acceptable range ) but there are a couple of use cases where every millisecond count. One of them is serverless applications which has become extremely popular in the last couple of years.
ZGC: Uncommit unused memory
ZGC ( Z Garbage Collector ) has been introduced in Java 11 as an experimental garbage collector. Its main goal is to perform all the gc tasks in a low latency manner, without stopping the execution of the application threads for more than 10 ms.
In the previous versions, this Garbage Collector was not able to uncommit the unused memory back to the operating system. In other words, if some of the memory was still unused by the JVM after a long time, the Garbage Collector should have freed up that memory and return it to the Operating System.
Reimplement the legacy Socket API
The already existing java.net.Socket and java.net.SocketServer API’s have been introduced in the JDK since version 1 so you can probably guess why an update was required. The old implementation was using a mix of legacy Java and C code which was painful to debug, it was running into some concurrency issues, and the underlying implementation was using the thread stack as the I/O buffer which required to often increase the default thread stack size.
The new implementation is more modern and it has also been designed as anticipation to fibers ( user-mode threads ) currently being explored in Project Loom.