VIM for Java Developers, Stream Gatherers, and The Ultimate Guide to Event-Driven Architecture in Java - JVM Weekly vol. 105
Today, it's more about practical stuff rather than news – but it won't be boring either. I have some really good long reads/watches to share.
1. Java in the Terminal - VIM for Java Developers
I must admit, I never became a member of the vim-user cult, but at the same time, my sophisticated (heh) sense of humor has never liked jokes about programmers who can't exit VIM (let's respect ourselves a bit, dear industry, pretty please). I've simply always had a subconscious admiration for people who perform magic in terminal editors. Are they more efficient? I don't think so, but watching them makes you look cool, like a hacker from 90s movies. I'll add that I've been exposed to a lot of Clojure in my life, and although it was long ago, I still keep in mind that Emacs is the super-IDE.
At the same time, I know that there are many fans of all kinds of VIM modes, and surely there are wannabes among the readers. So when I stumbled upon this gem, I couldn't help but share it:
Three full hours of material that turns VIM into a best-in-class (if you believe the author and the comments – as I said, that train has already left for me) IDE for Java. The material includes a lot of plugins, techniques, and ways of working. Everything you need to start, you have here.
And I know I've probably lost a good part of you now – both those who closed the tab thinking, "Who needs this?" and those who will spend the next 3 hours watching the above, using up their weekly self-development time budget (see you in the next edition!). But I still have some more findings for the rest of you.
The article Caveman Debugging in the Modern Age introduces (or rather name) the concept of Caveman Debugging, a primitive debugging method that involves placing print statements in code to track its behavior and monitor variable values.
In Poland, we call this 'Dupa Debug'—a well-loved technique in our community. Please, let's keep that term untranslated; it'll help me hang on to whatever scraps of professionalism you still think I have.
The author suggests combining this technique with Live Templates – a feature in IntelliJ IDEA that allows for quickly inserting predefined code snippets. For example, you can create templates that automatically print the class and function names and measure the execution time, making debugging and code analysis more effective than relying on the "magic" word...
...which you weren't supposed to translate, but I know you did.
The article's message is to encourage creating personalized code templates that suit your individual needs, analyzing your daily workflow, identifying repetitive, tedious tasks, and creating automatic templates for them. Automating repetitive things is the best use of your time... sort of.
2. Everything (and more) you wanted to know about Stream Gatherers... and serialization
Lately, it feels like new proposals have been piling up for me, so I've been skimming through them without giving proper context or adding my own insights. That's why today, I have a very focused exploration of Stream Gatherers for you. I still might not add that much of my own commentary, but I've collected so much material that I think you'll be more than satisfied after reading this section.
Even though the existing Stream API already offers a rich set of intermediate operations (like .map, .filter), sometimes there is a need to extend the list with more specialized ones, like fixedWindow(2) or scan((sum, next) -> sum + next). Through the years, JDK creators were bombed with repeated requests to add such additional operations to the Java 8 Stream API, which could be useful for some people, but their application is too narrow to include in the core Stream API without "cluttering" it. As a result, achieving certain results can sometimes be surprisingly difficult. Fortunately, a solution is on the horizon.
In the presentation Hunting with Stream Gatherers, 🥼Piotr Przybył (whose likeness I used as an inspiration for the main image of this section), Developer Advocate at Elastic, explains the concept of Stream Gatherers in Java - reactive streams built on a pull mechanism that include a source, intermediate operations, and terminal operations. Gatherers provide a way to collect and transform elements in a stream into different types while preserving state across executions. Piotr showcases the need for additional methods in the Java Stream API by creating a custom collector that filters words by their length and explores various types of gatherers, such as combine, finisher, and downstream, and demonstrates how concurrent streams and the Transformer function can be used to process elements into new forms.
Having covered that introduction (or rather a very in-depth look at the topic), we can move on to the other materials I have for you today. On the IntelliJ YouTube channel, there is an interview by Mala Gupta (Developer Advocate at JetBrains ) with Viktor Klang, the author of Akka and the creator of the entire specification, and Tagir Valeev, who is the author of the StreamEx library, which was a response to the earlier lack of a Stream Gatherers equivalent in the language. IMHO, it's not as accessible as Piotr's presentation, but it adds some interesting perspectives: on one hand, you have the original JEP's creator, and on the other, a person who previously had to deal with the language's limitations. I think Tagir's perspective is particularly interesting since we get a first-hand opinion from someone who has been tackling these challenges for many years.
StreamEx isn't the only project of this type recently. Grzegorz Piwowarek, who recently took over maintaining Vavr (as we mentioned), also created his own set of Stream Gatherers - pivovarit/more-gatherers. The project is still in development but is expected to be ready for JDK 24. Additionally, at the last JDD conference in Kraków, Grzegorz had a chance to talk about Stream Gatherers (as you can see, it's a popular topic), but unfortunately, it's not yet available – maybe someday, I'll be able to share it in the future.
Now you’ve got enough material on Streams to keep you busy for the next month—consider it your honorary PhD on the topic! But while we're at it, let me sneak in one more somehow related topic. Viktor Klang, the creator of the Stream Gatherers specification, recently took on the topic of object serialization in Java. Nicolai Parlog had a fantastic conversation with him, shedding light on the limitations of Java's serialization process. It’s definitely worth a listen!
Victor Klang explains the concept behind serialization, whose goal was to allow the conversion of class instances in memory to bytes for transmission over the network, but through the years has amassed challenges related to correctness and security. The topic was further expanded in a longer talk Serialization: A New Hope, where Klang and Brian Goetz dive deep into it, and I suspect you'll learn much more about serialization than you expected.
And to wrap up the topic, I'll spice it all up with one more Devoxx talk – as you can see, I'm also catching up on the backlog, and there's a lot of gold in that pot
The presentation Java's Cyclic Object Graphs Challenges, Stuart Marks from Oracle discusses the challenges of cyclic object graphs in Java, which can lead to infinite loops while traversing the graph, causing problems like stack overflow errors. Marks recommends steering clear of static initializers, opting for dependency injection, and constructing dependency graphs for static initialization to avoid cycles. He also advises against direct references to objects to prevent circular dependencies. Cyclic object graphs are a frequent headache, and while there are diagnostic tools available, the JDK doesn’t provide a comprehensive fix for the problem. It's a fascinating presentation that highlights how programming language creators grapple with complex challenges, diving deep into hardcore algorithms — though, let's be honest, that's hardly surprising at this point!
3. The Ultimate Guide to Event-Driven Architecture in Java
And finally, to conclude the Streams discussion (pun intended), let's talk about an event streaming system and event-driven architectures.
The article Event-driven architecture on the modern stack of Java technologies by Roman Kudryashov is exactly what the title and length promise – right from the title, it warns you with a reading time exceeding a whopping 100 minutes. It focuses on implementing a microservice-based system using the most important patterns of event-driven architecture, such as Transactional Outbox, Inbox, and Saga, using well-known technologies including Kotlin, Spring Boot, PostgreSQL, Kafka, Kafka Connect, and Debezium (which I mentioned just a week ago when version 3.0 was released). The article explains how to build a scalable and reliable event-based system and mix the mentioned technologies to help solve problems like double-write and message reliability by using ACID transactions in databases to efficiently manage outbox and inbox tables.
The core implementation includes three microservices: Book Service, User Service, and Notification Service, which communicate asynchronously via Kafka. A central element of the architecture is the use of Debezium connectors to capture database changes (meanwhile, Gunnar Morling published a few thoughts about CDC itself last week, worth checking IMHO) and stream them as events, allowing interaction between services without direct communication. This separation ensures that each service operates on its own data, and data consistency is managed through a choreography-based Saga pattern, where failures in local transactions trigger compensatory actions.
The article also covers the setup of supporting infrastructure, including Kafka Connect, Debezium, reverse proxy (Caddy), monitoring tools (Kafka UI and pgAdmin), and CI/CD pipelines. Additionally, the section on testing discusses various scenarios, including REST API tests, handling malformed messages, and testing communication between services..
It's a real beast that definitely deserves more attention - a fantastic piece and the most comprehensive one I've come across so far.
PS: Greetings from the conference tour, from OCX by Eclipse Foundation in Mainz and JDD in Kraków. This time, no detailed sharing (as the presentations are not available), but I still highly recommend the conferences – a chance for many inspiring conversations and meeting online faces in real life.
PS2: I messed up the volume numbering during the Devoxx edition, so I'm correcting it now. There will never be a 104 edition.