Diagrams, diagrams, diagrams: Classloaders and the Java Developer Roadmap - JVM Weekly vol. 99
The final countdown.
1. Diagrams, diagrams, diagrams: Classloaders and the Java Developer Roadmap
I have this tendency to drift off and start telling you about things that will appear in Java far in the future, to the point where only AI will be using them because human programmers will have long since died out. So today, in this first section, I have something more "every day" for you, but presented in an interesting way.
In the article How does the Java ClassLoader System really work? (with pictures), Yahor Barkouski uses a systematic, step-by-step approach to introduce the reader to how the class loading system works in Java. And he does all this with accessible graphics and diagrams that clearly explain each aspect. Yahor points out the many problems with imprecise or outdated information in popular sources (since we know Java evolves), which motivated him to explain the topic anew, from the ground up. He uses diagrams and code examples to break down the complex subject into easier-to-digest pieces.
The presentation of the information also has a nice hierarchy: first, the general principles of how the class loading system works, and then the specifics of the various loaders and stages of the process. The reader learns about the three main loaders: Bootstrap, Platform, and Application ClassLoader, their roles in the application startup process, and the delegation hierarchy between them. The author also discusses stages like Loading, Linking, and Initialization, such as finding the appropriate class files, verifying their integrity, allocating memory resources, and dynamically binding symbolic references to actual memory addresses.
For me, aside from the form, the most interesting aspect that runs through the text is the variety of JVM implementations (like HotSpot, GraalVM, or Eclipse OpenJ9) and their impact on performance and application functionality. The author explains how different JVMs may manage class loading differently, and that although Java is platform-independent, individual JVM implementations can behave differently in various environments.
And since we're on the topic of articles with diagrams, do you guys remember the Javarevisited blog by
(which now also has newsletter on Substack: )? I remember that when I first started learning the language and was preparing for my first interviews, it was my go-to place to prep for standard Q&A questions. I'm mentioning it because he recently updated his Roadmap for New Java Developers.The article presents a roadmap for Java developers, showing the key skills and technologies you need to master to become an expert in the field. The roadmap covers not only basic skills, like version control with Git, Linux system knowledge, and data structures and algorithms, but also creating, building, and deploying applications with tools like Docker, Jenkins, Maven, or Gradle. Additionally, the roadmap includes a section on frameworks (the author recommends learning Spring, Hibernate, and Spring Boot, but also suggests checking out Micronaut or Quarkus). Besides that, the roadmap touches on key libraries and APIs, such as Java Collections, Java Concurrency, and features introduced in Java 1.8, and even delves into AI, Web3, or reactive programming. The guide aims to simplify the learning process and outline the shortest path to gaining essential skills, with 2024 in mind for new developers.
And while we're on the topic of education, lastly, I have a small repository Zalaya/sorting-algorithms. The project aims to provide clear implementations of classic sorting algorithms in Java, such as Bubble Sort, Selection Sort, Insertion Sort, Merge Sort, Quick Sort, and Heap Sort, to help understand how they work and support decision-making on which algorithm to choose based on time complexity and specific use cases.
2. WebAssembly as an Alternative to FFI
We talked about Classloaders, and now let's talk about ways to bypass them — and in such a unique way that I just had to share it with you.
First, a bit of theory: Dynamic linking in Java involves loading native code at runtime, which can lead to security risks and memory management issues, as it bypasses the built-in JVM protection and optimization mechanisms. While dynamic linking is commonly used to integrate native libraries (e.g., SQLite) with Java applications, it exposes developers to problems — we no longer have strict memory management or platform independence. Of course, several mechanisms have been introduced over time to deal with this, such as Project Panama and the Foreign Function Interface (FFI). FFI introduces safer and more efficient mechanisms for integrating native libraries with Java applications, eliminating the need for JNI. But some people have more original ideas.
Are you familiar with WebAssembly? It’s an efficient, low-level binary format for web applications that allows code to run in the browser with near-native speed, regardless of the programming language in which it was written. However, what few people realize is that Wasm can be used outside the browser, bypassing the whole "web" aspect. Compiling native libraries to Wasm allows maintaining JVM performance and security guarantees while enabling the execution of a wide range of native code. Furthermore, Wasm's security model, based on resource access restrictions, ensures that code can only access system resources when explicitly permitted.
How does this relate to Java? Here, the text WebAssembly, the Safer Alternative to Integrating Native Code in Java by Benjamin Eckel comes to the rescue, which describes Chicory — a Wasm runtime for JVM that allows developers to run compiled Wasm code, such as SQLite, without dynamic linking. With Wasm's sandboxing and memory management, Chicory helps reduce the risks associated with native code while maintaining JVM performance. This is a promising solution for developers who want to use native libraries while retaining JVM security guarantees. I've been interested in WebAssembly for a long time (so long, in fact, that I've lost a bit of hope for its mainstream adoption, despite many interesting experiments and support from Docker, among others), so I’m eager to try this approach one day.
And speaking of unconventional approaches, there's a series of articles by Yorgos Smyrnaios on how Kotlin Native can work with Rust through FFI, using the sqlx4k project as an example. sqlx4k is a small, non-blocking PostgreSQL database driver written in Kotlin that internally uses the sqlx driver from the Rust ecosystem. Thanks to this collaboration, Kotlin can use Rust libraries by wrapping them in Kotlin code. The project is organized so that the Kotlin and Rust components are separate, and the Rust code is compiled as a static library, while Kotlin manages the communication via FFI. The Rust setup includes creating a static library and generating C headers using cbindgen, allowing communication with Kotlin — FFI at the moment only supports C.
The article shows that integrating Kotlin and Rust via FFI isn't some kind of black magic (though I don't recommend trying this at home). The author promised to explore the topic further in the future.
3. Release Radar
Spring-RS
Let’s start unusually with a Rust project — but one with an interesting source of inspiration.
spring-rs is an application framework written in Rust, inspired by Spring Boot. It follows the "convention over configuration" principle, simplifying the process of creating applications. A key feature of spring-rs is its extensible plugin system, which seamlessly integrates with popular projects in the Rust community, such as spring-web (based on axum), spring-sqlx (integrated with sqlx), spring-sea-orm, spring-redis, and spring-stream (for handling messages from redis-stream and kafka). The framework allows building complex applications with full support for message processing, telemetry (spring-opentelemetry), and background tasks (spring-job, integrated with tokio-cron-scheduler).
Now let’s look on the “real” radar
MicroProfile 7.0
Usually, MicroProfile, the standard that provides a set of APIs and tools for developing cloud-native applications based on Java EE standards, got its own section. This time, however, I decided to squeeze it into the Release Radar because while MicroProfile 7.0 brings interesting changes, its scope is narrower than it used to be.
It turns out that after support for the MicroProfile Metrics API, the metrics standard developed as part of MicroProfile, was dropped by Quarkus and WildFly, MicroProfile itself followed suit. One of the key changes in the new version is the decision that MicroProfile Metrics is no longer a component specification but an independent specification, not required for "certification" with MicroProfile. The newly released MicroProfile Telemetry 2.0 takes its place, integrating not only metrics but also logging and tracing functions in accordance with the OpenTelemetry standard from the Cloud Native Computing Foundation.
Breaking changes have appeared in MicroProfile Telemetry 2.0 and Open API 4.0. MicroProfile Rest Client 4.0 has also been released, but unlike the previous ones, it doesn't introduce additional breaking changes, aside from adaptation to Jakarta EE 10 Core Profile. Additionally, MicroProfile 7.0 now depends on Jakarta EE 10 Core Profile rather than packaging it directly.
Cassandra 5.0
Now, something unusual — let's talk about Cassandra... but we'll look at it from a rather unique perspective.
The news in Cassandra 5.0 concerns, among other things, improvements related to Java and performance. Did you know that until now, Cassandra was still running on Java 1.8? So, in the new release, the most important change is support for JDK 17, which improves memory management and boosts performance by up to 20%. The update also includes an integrated compression strategy that increases data density per node to over 10 terabytes, allowing companies to reduce the number of nodes needed for large operations and lower operational costs.
Cassandra 5.0 also introduces a new feature, Storage Attached Indexes (SAI), which allows for more flexible and efficient queries. Developers are no longer limited by rigid data models, as SAI makes it easier to query columns other than primary keys, reducing the complexity and overhead associated with secondary indexes.
Additionally, Cassandra 5.0 extends its suitability for applications related to the broad concept of "AI" (intentionally in quotes), introducing vector search and a new vector data type (though, as I understand it, the use of JVector will only appear in future releases). The release also includes new data structures based on tries, which streamline the data search process.
Clojure 1.20
It’s been a while since we last talked about Clojure, right? I feel like the language has lost some of its former glory and is less frequently mentioned alongside Kotlin, Scala, or even Groovy (though the latter has also gathered some dust). However, this doesn't mean the language's development has stalled, as evidenced by the new version.
Big changes have been announced under the hood. Although Clojure 1.12.0 still produces bytecode compatible with Java 8, this is the last release with that version, and future updates will require a newer LTS version of Java. In terms of compatibility, Clojure 1.12 addresses the pinning issue when using VirtualThreads in Java 21, replacing synchronized blocks in its internals with more efficient locking mechanisms, eliminating thread pinning warnings. Clojure 1.12 also introduces improvements in Java interoperability, such as support for functional interfaces and other "new" features from JDK 1.8, simplifying integration with Java code. The new API also allows easier control over external processes and stream handling via functions like stream-seq! and stream-reduce!. Operations on collections have also been optimized, including more efficient drop and partition methods for persistent collections, and support for parallel processing in PersistentVector through spliterators.
Additionally, new functions added in Clojure 1.12 enhance interactive use of libraries. Developers can now add libraries without restarting the JVM, which is useful when working on projects. Functions like add-lib and sync-deps allow dynamic library management during a REPL session, making it easier to experiment with new dependencies. The new invoke-tool function also allows running tools outside the current project dependencies, facilitating interactive use of tools without cluttering the classpath. Serialization support has also been improved to better control compatibility between Clojure versions.
bad 2.1.0
It's not the first time that bld has appeared in this review, but I always feel the need to remind people of the project's core ideas. Both Gradle and Maven are based on declarative build configurations, either using DSL (in Groovy or Kotlin) or XML. bld, on the other hand, allows programmers to write build logic in pure Java and was designed with ease of use in mind, emphasizing direct definition of the process, avoiding the "magic" often found in other build tools like Gradle. The philosophy behind the tool reminds me a lot of AWS's approach in the Cloud Development Kit.
The new version adds support for Java modules, Jpackage, Jmod, and Jlink operations, and also allows for the exclusion of source and Javadoc downloads for dependencies, shortening clean build times. Support for IntelliJ IDEA has been updated in the project creation template to recognize jar folder hierarchies, and the wrapper has been fixed to ensure the same Java environment is used for both the java executable and the javac compiler.
actor4k
The actor model on the JVM is mainly associated with Akka, but that doesn't mean there aren't other alternatives on our platform. Actor4k by Yorgos Smyrnaios (the already mentioned author of Kotlin/Rust/FFI article) is a simple actor system built in Kotlin and based on Coroutines, designed to work within a cluster. Actor4k uses the SWIM (Scalable Weakly-consistent Infection-style Membership) protocol — a decentralized algorithm for member discovery and failure detection in distributed systems, characterized by scalability, low network overhead, and providing partial consistency in detecting changes in topology. Nodes communicate via gRPC, and node management uses the Raft consensus algorithm.
Actor4k allows developers to create actors, define message handling logic, and send and receive messages using the provided API in both Kotlin and Java. As I mentioned earlier, the system also offers process control and communication via Kotlin coroutines, making it feel very "native" to that language.
langchain4j 0.34
The latest update to langchain4j 0.34 introduced integrations with Oracle Database Embedding Store and Couchbase Embedding Store. Additionally, a new type of tool was introduced — SearchApi — which currently defaults to Google Search. The SearchApi provides abstraction over search results, making the API consistent across major search engines. Also, we now have a new integration with Google Gemini AI. Several changes have also been made to existing services, including structural result handling in OpenAI, tool support in Ollama and Jlama, migration from Gson to Jackson in OpenAI, PgVector, and Redis, as well as support for approximate kNN searches in Elasticsearch and metadata filtering in Chroma and Pinecone.
Among the new features is the automatic extraction of JSON blocks before parsing LLM responses, returning sources identified during TokenStream usage, and dynamic tool selection in AI services.
Visual Studio Code Extension
Oracle has released version 22.1.2 of its Java extension for Visual Studio Code. The update supports early versions of OpenJDK 23, and key fixes include proper handling of Source Actions and adjusting the launch configuration panel when there's no workspace. Other improvements include support for @SuppressWarnings annotations for unused code elements, support for less common JavaDoc tags like {@index ...} and {@summary ...}, and displaying constructor JavaDocs when hovering over a specific instance in the code.
Oracle Code Assist - Beta
This week at Oracle CloudWorld, the company announced that Oracle Code Assist (OCA) — their AI coding assistant — has entered beta. OCA is designed to help developers code faster, especially in enterprise projects, with a strong focus on legacy systems. While most of the communication has focused on Java, it also supports many programming languages, including JavaScript, Python, SuiteScript, and SQL, with optimization for NetSuite's SuiteScript.
Key features include automatic code generation, unit test creation, documentation generation, and code analysis for optimization. Although Oracle has not revealed what data was used to train OCA models, the company claims it leverages its rich experience in the Java community to offer high-quality automation code recommendations. Oracle also ensures that no code or personal data is stored when using the tool (which is often a barrier to adopting such solutions in many enterprise applications). Interested users can apply to join the beta program, and more details on integrating OCA into daily development processes, such as code review and debugging, will be revealed in the coming days at Oracle CloudWorld.
PS: I had a false start again... there are already new talks from JVMLS. When the next batch comes out, we’ll have to do another review session.
PS2: Next week marks the 100th edition! I can hardly believe it. Get ready for some (albeit cosmetic) changes 😃
Thank you for mention, appreciate it.