Best of Foojay.io July 2024 Edition – JVM Weekly vol. 92
Another month, another roundup of articles from Foojay. Although it's vacation season, I think I've managed to dig up some cool stuff for you.
Let's start, as usual, with the podcast.
Foojay Podcast #55: Embedded Java, Part 2
In the latest episode of the Foojay podcast, Foojay Podcast #55: Embedded Java, Part 2, the team delves once again into the world of Java on embedded devices, revisiting a topic discussed nearly three years ago in the second episode of the series. This is an interesting return to roots because, initially designed for set-top boxes and gateways, Java has undergone an intriguing evolution into the versatile language we know today.
The podcast explores Java's beginnings with the Micro Edition and discusses its current capabilities on modern embedded devices like Raspberry Pi Zero and RISC-V. Host Frank Delporte and his guests, Robert von Burg, DaShaun Carter, and Pavel Petroshenko, share their insights on Java's adaptability and "green computing."
beetRoot: Yet Another Web Framework?
I remember the time when everyone laughed at JavaScript because it seemed like a new framework or library appeared every day. It seems that the situation has stabilized somewhat now, with developers complaining more about "bloat" rather than "fatigue" (as discussed in a recently published, excellent text by Nikita Prokopov).
Interestingly, recently I have noticed more and more Java solutions trying to steal some popularity from the biggest players. One of them is beetRoot by Michael Gasche.
The article beetRoot: Yet Another Web Framework? discusses the author's experiences with various frameworks for creating web applications in Java and explains why he decided to create yet another solution (whether independently or as part of the company he is CEO of, Michael is not specific on this in the text). Perhaps the most interesting thing about beetRoot is its inspiration. The author wanted to create a comprehensive Java framework similar to the often scorned PHP frameworks like CakePHP or Laravel.
It is a solution that includes essential features such as CSRF prevention, 2FA authentication, CRUD generation, and compatibility with various web frameworks. The configuration of beetRoot is simple, reminiscent of CakePHP's approach, with a full CRUD generator that creates views, models, and controllers based on the database model.
beetRoot is compatible with Apache Tomcat, Eclipse Jetty, and Oracle WebLogic. Plans for beetRoot version 3.0.0 include improved user roles, better management of many-to-many relationships, UI redesign, and overall improvements.
Structured Concurrency is More Than ShutdownOnFailure
Continuing with lesser-known projects, let's take a look at Structured Concurrency – a topic that's one of my "darlings." This is because the development of this functionality in Kotlin was one of the first language features I followed closely from the original announcement and armed with that knowledge, I later had a chance to get a good grasp of its subsequent iterations of concept in Java itself. Nonetheless, what I love about this ecosystem is that even in such situations, someone can still surprise me, and that someone today is Anthony Goubard.
Anthony published Structured Concurrency is More Than ShutdownOnFailure. The article begins by explaining the basic concept of structured concurrency, which involves task scopes ShutdownOnSuccess
and ShutdownOnFailure
, providing the reader with the basics of how structured concurrency simplifies the management of parallel tasks. For reference, these classes either stop the scope and its current subtasks when one task succeeds or fails.
Where most articles would end, Anthony's article goes further, presenting his created library Virtually, which enables easier migration of code to a more thread-friendly environment, minimizing the need for extensive helper code. This library offers tools such as utilities and annotations replacing synchronized
, list conversion methods using virtual threads, and classes for executing tasks in these threads. For instance, Virtually also allows replacing synchronized code blocks with ReentrantLock
or collection conversion.
From the perspective of structured concurrency, the most interesting addition is EnhancedTaskScope
. EnhancedTaskScope
includes features such as throttling, which limits the number of concurrent tasks to prevent system overload and a circuit breaker mechanism that halts execution when too many tasks fail. Additionally, it allows for providing default values for tasks that fail, ensuring smooth application operation. This makes EnhancedTaskScope
an exceptionally useful tool for managing complex operations, utilizing structured concurrency for effective task processing.
It's worth noting that the library is in the early stages of development, meaning there is no backward compatibility guarantee. However, I must admit that I didn't know about this tool, and it significant refreshment from yet-another article on the basics of Structured Concurrency. And if you're still craving more on this topic after reading, the official Java channel recently released a talk by Alan Bateman, presenting the project's development:
What’s wrong with createDirectories? – A Beginner’s Guide to IntelliJ Profiler
Having covered projects with fewer than 100 stars on GitHub, it's time for something practical after fulfilling the mission. I suspect that none of my readers compile code written in Notepad (no, VSCode is not a notepad 😉), but rather in an IDE. However, I suspect – and looking at the quarterly release notes of new IntelliJ versions, this suspicion is close to certainty – that many of us (myself included) do not fully utilize the tools' capabilities.
That's why I think it's worth taking a look at the article What’s wrong with createDirectories? – A Beginner’s Guide to IntelliJ Profiler by Igor Kulakov from JetBrains, which highlights the importance of profiling, even for simple applications. He uses an example program, specifically focusing on the createDirectories()
method from the NIO2 library, to show how profiling, even using the standard IntelliJ Profiler, can reveal inefficiencies. The program measures the performance of this method by repeatedly creating a file system path and measuring throughput.
The article ends by emphasizing the value of profiling in identifying and fixing performance bottlenecks, even in small applications. It shows that understanding how even well-known APIs work can lead to significant performance improvements. The author encourages readers to explore more profiling techniques and use cases in future articles.
The Best Way to Handle Phone Numbers
Have you ever worked with dates, addresses, or languages? If so, you know that there are dragons lurking for the unwary traveler.
It's no different with processing phone numbers, especially in applications for the international market. Fortunately, Google's libphonenumber
library, created for mobile applications and Android, simplifies this task significantly. The article The Best Way to Handle Phone Numbers by Simon Martinelli from Vaadin discusses its capabilities, such as parsing, formatting, and validating international phone numbers, using an extensive set of metadata from various regions. The library also includes advanced features like identifying phone numbers in text and determining their types. It is thus an "ideal utility," encapsulating the complexity of a specific domain in an easy-to-use tool.
I recommend libphonenumber
; I use it, and it really helps reduce the number of gray hairs on your head. A small thing, but it can prolong our lives by a few weeks.
Unsafe is Finally Going Away: Embracing Safer Memory Access with JEP 471
Good things should rhyme, they say, so just like last month, we'll end today with an article by A N M Bazlur Rahman, this time presenting alternatives to sun.misc.Unsafe.
A quick recap: Java typically prevents low-level memory access, restricting memory management mainly to the heap. However, for some performance-critical tasks, library developers sometimes need to manipulate memory outside the heap. This is where the controversial sun.misc.Unsafe
class comes in, offering powerful but dangerous capabilities that can lead to serious problems like memory leaks, crashes, and security vulnerabilities if used improperly. Recognizing the risks, the Java community has long sought safer alternatives, ultimately leading to JEP 471, which marks the deprecation of memory access methods in sun.misc.Unsafe
, paving the way for their eventual removal.
However, it's not enough to just remove something without providing an alternative. Therefore, to meet the need for safe and efficient memory manipulation, Java introduced two standard APIs: the VarHandle API and the Foreign Function & Memory API. The VarHandle API, introduced in JDK 9, provides safe variable access with built-in safety features. The Foreign Function & Memory API, available since JDK 22, enables safe interaction with native memory and functions.
In the publication, A N M Bazlur Rahman illustrates how to transition to these APIs with a simple example of the AtomicCounter
class, traditionally implemented using sun.misc.Unsafe
, now rewritten using VarHandle
. I recommend it; it's a very nice, easy-to-understand, and isolated example.
And that's all for now, we’ll return to Foojay.io articles next month. Next week we'll return to the standard edition, and I'm already excited for the release radar.