<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.roray.dev/feed_style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <tabi:metadata xmlns:tabi="https://github.com/welpo/tabi">
        <tabi:base_url>https:&#x2F;&#x2F;www.roray.dev</tabi:base_url>
        <tabi:separator>
            •
        </tabi:separator>
        <tabi:about_feeds>This is a web feed, also known as an Atom feed. Subscribe by copying the URL from the address bar into your newsreader. Visit About Feeds to learn more and get started. It&#x27;s free.</tabi:about_feeds>
        <tabi:visit_the_site>Visit website</tabi:visit_the_site>
        <tabi:recent_posts>Recent posts</tabi:recent_posts>
        <tabi:last_updated_on>Updated on $DATE</tabi:last_updated_on>
        <tabi:default_theme></tabi:default_theme>
        <tabi:post_listing_date>date</tabi:post_listing_date>
        <tabi:current_section>backend</tabi:current_section>
    </tabi:metadata><link rel="extra-stylesheet" href="https://www.roray.dev/skins/lowcontrast_orange.css?h=43aaccb17d8ec616ace4" /><title>roray.dev - backend</title>
        <subtitle>home of Rohan Ray&#x27;s coding world</subtitle>
    <link href="https://www.roray.dev/tags/backend/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://www.roray.dev/tags/backend/" rel="alternate" type="text/html"/>
    <generator uri="https://www.getzola.org/">Zola</generator><updated>2025-08-28T00:00:00+00:00</updated><id>https://www.roray.dev/tags/backend/atom.xml</id><entry xml:lang="en">
        <title>Java FFM - Foreign Function &amp; Memory Access API (Project Panama)</title>
        <published>2025-08-28T00:00:00+00:00</published>
        <updated>2025-08-28T00:00:00+00:00</updated>
        <author>
            <name>Rohan Ray</name>
        </author>
        <link rel="alternate" href="https://www.roray.dev/blog/java-io-uring-ffm/" type="text/html"/>
        <id>https://www.roray.dev/blog/java-io-uring-ffm/</id>
        
            <content type="html">&lt;h1 id=&quot;tl-dr&quot;&gt;TL;DR&lt;&#x2F;h1&gt;
&lt;p&gt;Java’s Foreign Function &amp;amp; Memory (FFM) API enables safe, high-performance interaction with native code and memory, improving interoperability with other languages and access to low-level system resources. Entire source code available on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rohanray&#x2F;roray-dev-site&#x2F;tree&#x2F;main&#x2F;code&#x2F;java-iouring-tcp-echo&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;GitHub&lt;&#x2F;a&gt;.
&lt;br&gt;
&lt;br&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h1&gt;
&lt;p&gt;
The Foreign Function &amp; Memory (FFM) API in Java, finalized in JDK 22 with JEP 454, provides a robust and safe mechanism for Java code to interact with foreign functions (native code) and foreign memory (memory outside the Java heap).
&lt;&#x2F;p&gt;
&lt;p&gt;
The FFM API is designed to be a safer, more efficient, and more user-friendly alternative to the Java Native Interface (JNI). JNI is known for its complexity and potential for introducing errors, whereas FFM aims to provide a more &quot;Java-first&quot; programming model for native interoperability.
&lt;&#x2F;p&gt;
&lt;p&gt;
The FFM API introduces several key concepts and components that facilitate foreign function and memory access in Java:
&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory Segments&lt;&#x2F;strong&gt;: A memory segment is a contiguous block of memory that can be accessed by Java programs. The FFM API provides a way to create and manage memory segments, allowing developers to allocate and deallocate memory as needed.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Arena Allocation&lt;&#x2F;strong&gt;: The FFM API introduces the concept of arenas, which are memory pools that can be used for efficient allocation and deallocation of memory. Arenas help reduce fragmentation and improve performance when working with native memory.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Value Layouts&lt;&#x2F;strong&gt;: Value layouts define the memory layout of data structures in a platform-independent way. The FFM API allows developers to create value layouts for both Java and foreign types, ensuring compatibility between the two.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory Access&lt;&#x2F;strong&gt;: The FFM API provides a set of APIs for reading and writing data to memory segments, making it easy to manipulate native data from Java.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Foreign Functions&lt;&#x2F;strong&gt;: Foreign functions are native functions written in languages like C or C++ that can be called from Java. The FFM API provides a way to define and invoke foreign functions, enabling seamless integration between Java and native code.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: &lt;em&gt;While the primary use case of the Java Foreign Function &amp;amp; Memory (FFM) API is to call C functions from Java (downcalls), it also supports the reverse: calling Java functions from C (upcalls). This is particularly useful for scenarios like C callbacks, where a C library needs to invoke a function provided by Java code.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;br&gt;
&lt;h1 id=&quot;ffm-use-cases&quot;&gt;FFM Use cases&lt;&#x2F;h1&gt;
&lt;p&gt;By leveraging these components, developers can build high-performance applications that take advantage of native libraries and system resources while maintaining the safety and ease of use that Java provides especially in below use cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Performance-Critical Applications&lt;&#x2F;strong&gt;: Applications that require high performance such as game engines, scientific computing, Ultra Low Level (ULL) High Frequency Trading (HFT) systems and real-time systems can benefit from direct access to native code and memory.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Big Data and Machine Learning&lt;&#x2F;strong&gt;: Libraries like TensorFlow and PyTorch often require efficient memory management and native code execution, making FFM a suitable choice for integrating these libraries into Java applications.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Interoperability with Other Languages&lt;&#x2F;strong&gt;: FFM allows Java applications to easily call functions written in other languages, such as C or C++, enabling developers to leverage existing libraries and codebases&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Low-Level System Access&lt;&#x2F;strong&gt;: Applications that need to interact with low-level system resources, such as hardware devices or operating system APIs, can use FFM to access these resources directly from Java e.g. accessing NIC for Kernel bypass networking, accessing GPU for parallel processing, etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;High Performance Computing (HPC)&lt;&#x2F;strong&gt;: FFM can be used in HPC applications where performance is critical, such as simulations, numerical computations, and data processing tasks that require efficient memory management and native code execution.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;High Performance File&#x2F;Data I&#x2F;O&lt;&#x2F;strong&gt;: Database files, large binary files, and other data-intensive applications can benefit by using techniques like memory-mapped files which allow direct access to file contents in memory, random access, bulk read, minimize OS calls, Zero copy &amp;amp; low GC pressure by avoiding Heap, multi-process file coordination with locks improving I&#x2F;O performance and reducing latency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Custom High Performance Low Latency RPC&lt;&#x2F;strong&gt;: Remote Procedure Calls (RPC) can be optimized using FFM to reduce serialization&#x2F;deserialization overhead, enabling faster communication with high throughput between distributed systems.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;br&gt;
&lt;h1 id=&quot;demo-example&quot;&gt;Demo Example&lt;&#x2F;h1&gt;
&lt;p&gt;Let’s see a small example of effective usage of FFM. As a Proof of Concept, we will create a TCP server using &lt;a href=&quot;https:&#x2F;&#x2F;developers.redhat.com&#x2F;articles&#x2F;2023&#x2F;04&#x2F;12&#x2F;why-you-should-use-iouring-network-io&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;io_uring&lt;&#x2F;a&gt; (Linux kernel interface for asynchronous I&#x2F;O operations) and Java FFM API. The actual TCP server using io_uring is implemented in C. We will use various APIs (standard TCP operations) viz. accept, listen, connect, send, receive etc. in Java through Foreign Functions mapping the actual C functions.&lt;&#x2F;p&gt;
&lt;p&gt;This is by no means a production ready code. The goal is to showcase the ease of use and integration of FFM with existing C libraries. We also won’t be going into details of TCP server implementation in C nor what is io_uring as it’s beyond the scope of this article.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;h2 id=&quot;tcp-server-in-c-using-async-io-uring&quot;&gt;TCP server in C using async io-uring&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s look at the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rohanray&#x2F;roray-dev-site&#x2F;blob&#x2F;main&#x2F;code&#x2F;java-iouring-tcp-echo&#x2F;c-iouring&#x2F;io_uring_tcp_io.c&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C code&lt;&#x2F;a&gt; first especially the below APIs:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io_uring_global_init&lt;&#x2F;code&gt; - Initializes the global io_uring context and sets up the underlying ring buffers for asynchronous I&#x2F;O operations&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;io_uring_listen&lt;&#x2F;code&gt; - Creates a TCP socket, binds it to a specified port, and starts listening for incoming connections&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;io_uring_accept&lt;&#x2F;code&gt; - Accepts an incoming connection request and returns a new socket file descriptor for the client&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;io_uring_connect&lt;&#x2F;code&gt; - Establishes an outbound TCP connection to a remote server at the specified address and port&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;io_uring_send&lt;&#x2F;code&gt; - Sends data through an established TCP connection using io_uring’s asynchronous write operations&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;io_uring_receive&lt;&#x2F;code&gt; - Receives data from an established TCP connection using io_uring’s asynchronous read operations&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;java-ffm-integration&quot;&gt;Java - FFM Integration&lt;&#x2F;h2&gt;
&lt;p&gt;Now let’s look at the Java side which is the point of interest of this article. We have 2 classes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FfmReceiver&lt;&#x2F;code&gt; - Responsible for receiving data from the TCP server&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FfmSender&lt;&#x2F;code&gt; - Responsible for sending data to the TCP server&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Note: &lt;strong&gt;The actual TCP server is implemented in C using io_uring. The C library exposes lifecycle methods for managing the server. These methods are then called in Java using FFM.&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ffmreceiver&quot;&gt;FfmReceiver&lt;&#x2F;h3&gt;
&lt;pre data-linenos data-lang=&quot;FfmReceiver.java&quot; class=&quot;language-FfmReceiver.java z-code&quot;&gt;&lt;code class=&quot;language-FfmReceiver.java&quot; data-lang=&quot;FfmReceiver.java&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.Arena;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.FunctionDescriptor;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.Linker;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.MemorySegment;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.SymbolLookup;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.ValueLayout;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.invoke.MethodHandle;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.nio.charset.StandardCharsets;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;public class FfmReceiver {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    private static final ValueLayout.OfByte BYTE = ValueLayout.Java_BYTE;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    public static void main(String[] args) throws Throwable {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        int queueDepth = 32;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        int port = 22345;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        int backlog = 128;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        long bufferSize = 8 * 1024 * 1024; &#x2F;&#x2F; 8 MB buffer per client
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        try (Arena arena = Arena.ofShared()) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; Load the shared library
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            SymbolLookup lib = SymbolLookup.libraryLookup(&amp;quot;.&#x2F;libiouring_tcp.so&amp;quot;, arena);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            Linker linker = Linker.nativeLinker();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; 1️⃣ Global Init
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment globalInitAddr = lib.find(&amp;quot;io_uring_global_init&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle mhGlobalInit = linker.downcallHandle(globalInitAddr,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    FunctionDescriptor.of(ValueLayout.Java_INT, ValueLayout.Java_INT));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            int ret = (int) mhGlobalInit.invokeExact(queueDepth);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            System.out.println(&amp;quot;io_uring_global_init returned: &amp;quot; + ret);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; 2️⃣ Listen (server socket)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment listenAddr = lib.find(&amp;quot;io_uring_listen&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle mhListen = linker.downcallHandle(listenAddr,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    FunctionDescriptor.of(ValueLayout.Java_INT, ValueLayout.Java_INT, ValueLayout.Java_INT));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            int listenFd = (int) mhListen.invokeExact(port, backlog);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            if (listenFd &amp;lt; 0) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                throw new RuntimeException(&amp;quot;io_uring_listen failed, fd=&amp;quot; + listenFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            System.out.println(&amp;quot;Server listening on port &amp;quot; + port + &amp;quot;, fd=&amp;quot; + listenFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; 3️⃣ Accept clients in a loop
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment acceptAddr = lib.find(&amp;quot;io_uring_accept&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle mhAccept = linker.downcallHandle(acceptAddr,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;46&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    FunctionDescriptor.of(ValueLayout.Java_INT, ValueLayout.Java_INT));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;47&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment recvAddr = lib.find(&amp;quot;io_uring_recv&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle mhRecv = linker.downcallHandle(recvAddr,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;50&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    FunctionDescriptor.of(ValueLayout.Java_INT, ValueLayout.Java_INT, ValueLayout.ADDRESS, ValueLayout.Java_LONG));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;51&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;52&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            while (true) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;53&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                int clientFd = (int) mhAccept.invokeExact(listenFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;54&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                if (clientFd &amp;lt; 0) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;55&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    System.err.println(&amp;quot;Accept failed, fd=&amp;quot; + clientFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    continue;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;57&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;58&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                System.out.println(&amp;quot;Client connected, fd=&amp;quot; + clientFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;59&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;60&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &#x2F;&#x2F; Allocate buffer for this client
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;61&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                MemorySegment buffer = arena.allocate(bufferSize);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;62&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;63&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                int bytesReceived = (int) mhRecv.invokeExact(clientFd, buffer, bufferSize);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                if (bytesReceived &amp;lt; 0) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;65&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    System.err.println(&amp;quot;io_uring_recv failed, bytes=&amp;quot; + bytesReceived);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;66&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    continue;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;67&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;68&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                System.out.println(&amp;quot;Received bytes: &amp;quot; + bytesReceived);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;69&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;70&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &#x2F;&#x2F; Print first 128 bytes for debugging (optional)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;71&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                int displayLen = Math.min(128, bytesReceived);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;72&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                byte[] arr = new byte[displayLen];
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;73&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                for (int i = 0; i &amp;lt; displayLen; i++) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;74&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    arr[i] = buffer.get(BYTE, i);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;75&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;76&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                System.out.println(&amp;quot;First &amp;quot; + displayLen + &amp;quot; bytes:\n&amp;quot; +
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;77&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                        new String(arr, StandardCharsets.US_ASCII));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;79&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &#x2F;&#x2F; Close client socket
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                MemorySegment closeAddr = lib.find(&amp;quot;io_uring_close&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;81&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                MethodHandle mhClose = linker.downcallHandle(closeAddr,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;82&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                        FunctionDescriptor.ofVoid(ValueLayout.Java_INT));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;83&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                mhClose.invokeExact(clientFd);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;84&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                System.out.println(&amp;quot;Client fd &amp;quot; + clientFd + &amp;quot; closed.&amp;quot;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;85&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;86&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;87&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; 4️⃣ Optional: shutdown ring (never reached in infinite loop)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;88&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; MemorySegment shutdownAddr = lib.find(&amp;quot;io_uring_global_shutdown&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;89&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; MethodHandle mhShutdown = linker.downcallHandle(shutdownAddr, FunctionDescriptor.ofVoid());
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;90&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; mhShutdown.invokeExact();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;91&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;92&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;93&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This FfmReceiver class demonstrates a complete FFM workflow for calling native C functions from Java. Here’s the high-level technical breakdown:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Library Loading &amp;amp; Symbol Resolution&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;FFM loads the compiled C shared library containing io_uring functions. SymbolLookup provides a bridge to find C function symbols by name.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Key FFM Components in Action&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Arena: Manages native memory lifecycle - automatically frees all allocated memory when closed (safe malloc&#x2F;free).&lt;&#x2F;li&gt;
&lt;li&gt;SymbolLookup: This is how Java finds function pointers in a native library. Think of SymbolLookup as a “directory of functions” inside the .so file.&lt;&#x2F;li&gt;
&lt;li&gt;Linker: The bridge between Java and native code, which knows how to convert between Java calling conventions and the platform’s native ABI (x86_64 Linux, ARM64, etc.).&lt;&#x2F;li&gt;
&lt;li&gt;FunctionDescriptor: Defines the C&#x2F;native function signature (return type + parameter types)&lt;&#x2F;li&gt;
&lt;li&gt;ValueLayout: Maps Java types to native types (Java_INT → C int, ADDRESS → C pointer)&lt;&#x2F;li&gt;
&lt;li&gt;MethodHandle: Type-safe wrapper for C&#x2F;native function calls&lt;&#x2F;li&gt;
&lt;li&gt;MemorySegment: Represents native memory buffers for data exchange; essentially a safe pointer with guardrails.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Memory Management&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Native memory is allocated outside the Java heap. Data is directly read&#x2F;written to native buffers without copying (zero copy). Arena ensures safe &amp;amp; automatic cleanup when the try-with-resources block exits.&lt;&#x2F;p&gt;
&lt;p&gt;Here, arena is used both to load the library and allocate buffers for receiving data.&lt;&#x2F;p&gt;
&lt;p&gt;Here, libraryLookup loads our custom shared library (.so) and lets us find symbols like io_uring_global_init, io_uring_listen, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Then with linker, we can create MethodHandles that behave like normal Java methods but actually invoke C functions. We can think of a MethodHandle as a Java wrapper around a native C function. A linker can be thought of as a translator between Java’s JVM world and C’s native&#x2F;binary code.&lt;&#x2F;p&gt;
&lt;p&gt;Next, we define the function signature with FunctionDescriptor.of(Java_INT, Java_INT) which includes parameter(input) types &amp;amp; all return types. In this case, the function says it takes one int argument &amp;amp; returns one int as the result. invokeExact(queueDepth) → actually executes the C function.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Safety &amp;amp; Type Checking&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;invokeExact() enforces exact type matching between Java and C function signatures. Compile-time validation prevents type mismatches that would cause runtime errors. No manual memory management or pointer arithmetic required. This approach eliminates JNI’s complexity while providing direct, high-performance access to native libraries with Java’s safety guarantees intact.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Click &lt;a href=&quot;#memo-walking-through-ffmreceiver-a-first-taste-of-java-ffm-ai-generated&quot;&gt;here&lt;&#x2F;a&gt; to see a more detailed AI generated walk through of FfmReceiver implementation.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sample Output:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;ffmreceiver-output.png&quot; alt=&quot;alt text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ffmsender&quot;&gt;FfmSender&lt;&#x2F;h3&gt;
&lt;pre data-linenos data-lang=&quot;FfmSender.java&quot; class=&quot;language-FfmSender.java z-code&quot;&gt;&lt;code class=&quot;language-FfmSender.java&quot; data-lang=&quot;FfmSender.java&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.foreign.*;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.lang.invoke.MethodHandle;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import java.nio.charset.StandardCharsets;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;public class FfmSender {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    public static void main(String[] args) throws Throwable {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        int queueDepth = 32;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        int port = 22345;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        long bufferSize = 4 * 1024; &#x2F;&#x2F; 4 KB buffer per client
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        System.out.println(&amp;quot;FfmSender running...&amp;quot;);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        try (Arena arena = Arena.ofShared()) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            String hi = &amp;quot;ping&amp;quot;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; Load the shared library
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            SymbolLookup lib = SymbolLookup.libraryLookup(&amp;quot;.&#x2F;libiouring_tcp.so&amp;quot;, arena);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            Linker linker = Linker.nativeLinker();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; Global IO URing Init
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment globalInitAddrMS = lib.find(&amp;quot;io_uring_global_init&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            FunctionDescriptor globalInitFD = FunctionDescriptor.of(
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle globalInitMH = linker.downcallHandle(globalInitAddrMS, globalInitFD);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            int ret = (int) globalInitMH.invokeExact(queueDepth);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            System.out.println(&amp;quot;io_uring_global_init returned: &amp;quot; + ret);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; TCP Open Socket FD
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment tcpSocketAddrMS = lib.find(&amp;quot;io_uring_connect&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            FunctionDescriptor tcpConnectFD = FunctionDescriptor.of(
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT, &#x2F;&#x2F; return value of socket File Descriptor
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.ADDRESS, &#x2F;&#x2F; server address
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT); &#x2F;&#x2F; server port
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle tcpConnectMH = linker.downcallHandle(tcpSocketAddrMS, tcpConnectFD);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            String ip = &amp;quot;127.0.0.1&amp;quot;; &#x2F;&#x2F; destination IP
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            byte[] ipBytes = ip.getBytes(StandardCharsets.UTF_8);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment ipStr = arena.allocate(ipBytes.length + 1);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            ipStr.asSlice(0, ipBytes.length).copyFrom(MemorySegment.ofArray(ipBytes));
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            ipStr.set(ValueLayout.Java_BYTE, ipBytes.length, (byte) 0); &#x2F;&#x2F; Null-terminate for C
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            int socketFD = (int) tcpConnectMH.invokeExact(ipStr, port);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; IO URing send data through memory segment off-heap buffer
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment sendBufAddrMS = lib.find(&amp;quot;io_uring_send_all&amp;quot;).get();
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;46&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            FunctionDescriptor sendBufFD = FunctionDescriptor.of(
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;47&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT, &#x2F;&#x2F; return value: total sent bytes
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_INT, &#x2F;&#x2F; socket fd
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.ADDRESS, &#x2F;&#x2F; buffer address
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;50&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                    ValueLayout.Java_LONG); &#x2F;&#x2F; buffer length
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;51&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MethodHandle sendBufMH = linker.downcallHandle(sendBufAddrMS, sendBufFD);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;52&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;53&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &#x2F;&#x2F; Prepare buffer
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;54&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            MemorySegment sendBuf = arena.allocateFrom(hi);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;55&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            int totalBytesSent = (int) sendBufMH.invokeExact(socketFD, sendBuf, (long) hi.length());
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;57&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;58&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            System.out.println(&amp;quot;Total bytes sent Java FFM: &amp;quot; + totalBytesSent);
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;59&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;60&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;61&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;62&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;63&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Sample Output:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;ffmsender-output.png&quot; alt=&quot;alt text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This FfmSender class demonstrates sending data to the TCP server using FFM. The flow is similar to FfmReceiver. We send “ping” text to the TCP Server &amp;gt; FfmReceiver.&lt;&#x2F;p&gt;
&lt;br&gt;
&lt;h1 id=&quot;appendix&quot;&gt;Appendix&lt;&#x2F;h1&gt;
&lt;h3 id=&quot;java-versions-support&quot;&gt;Java Versions support&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;JDK Version&lt;&#x2F;th&gt;&lt;th&gt;API Status&lt;&#x2F;th&gt;&lt;th&gt;Enabling Preview Features&lt;&#x2F;th&gt;&lt;th&gt;Key Enhancements (FFM API versions)&lt;&#x2F;th&gt;&lt;th&gt;Package&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 14&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Foreign-Memory Access API (Incubator)&lt;&#x2F;td&gt;&lt;td&gt;Not applicable (Incubator)&lt;&#x2F;td&gt;&lt;td&gt;Memory segments, Arenas (via Foreign-Memory Access API)&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;14&#x2F;docs&#x2F;api&#x2F;jdk.incubator.foreign&#x2F;jdk&#x2F;incubator&#x2F;foreign&#x2F;package-use.html&quot;&gt;jdk.incubator.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 16&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Incubator&lt;&#x2F;td&gt;&lt;td&gt;Not applicable (Incubator)&lt;&#x2F;td&gt;&lt;td&gt;Calling native functions (via Foreign Linker API)&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;16&#x2F;docs&#x2F;api&#x2F;jdk.incubator.foreign&#x2F;jdk&#x2F;incubator&#x2F;foreign&#x2F;package-use.html&quot;&gt;jdk.incubator.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 17&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Incubator&lt;&#x2F;td&gt;&lt;td&gt;Not applicable (Incubator)&lt;&#x2F;td&gt;&lt;td&gt;Unified FFM API, enhancements to MemorySegment and MemoryAddress abstractions, improved memory layout hierarchy&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;17&#x2F;docs&#x2F;api&#x2F;jdk.incubator.foreign&#x2F;jdk&#x2F;incubator&#x2F;foreign&#x2F;package-use.html&quot;&gt;jdk.incubator.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 18&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Incubator&lt;&#x2F;td&gt;&lt;td&gt;Not applicable (Incubator)&lt;&#x2F;td&gt;&lt;td&gt;Refinements based on feedback&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;18&#x2F;docs&#x2F;api&#x2F;jdk.incubator.foreign&#x2F;jdk&#x2F;incubator&#x2F;foreign&#x2F;package-use.html&quot;&gt;jdk.incubator.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 19&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Preview&lt;&#x2F;td&gt;&lt;td&gt;–enable-preview flag required&lt;&#x2F;td&gt;&lt;td&gt;Refinements based on feedback&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;19&#x2F;docs&#x2F;api&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;foreign&#x2F;package-summary.html&quot;&gt;java.lang.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 20&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Second Preview&lt;&#x2F;td&gt;&lt;td&gt;–enable-preview flag required&lt;&#x2F;td&gt;&lt;td&gt;Refinements based on feedback, including linker option for heap segments, Enable-Native-Access attribute, programmatic function descriptors&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;20&#x2F;docs&#x2F;api&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;foreign&#x2F;package-summary.html&quot;&gt;java.lang.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 21&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Third Preview&lt;&#x2F;td&gt;&lt;td&gt;–enable-preview flag required&lt;&#x2F;td&gt;&lt;td&gt;Further refinements based on feedback&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;21&#x2F;docs&#x2F;api&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;foreign&#x2F;package-summary.html&quot;&gt;java.lang.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JDK 22+&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Finalized&lt;&#x2F;td&gt;&lt;td&gt;Not required (Finalized)&lt;&#x2F;td&gt;&lt;td&gt;API stabilization, minor refinements&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.oracle.com&#x2F;en&#x2F;java&#x2F;javase&#x2F;22&#x2F;docs&#x2F;api&#x2F;java.base&#x2F;java&#x2F;lang&#x2F;foreign&#x2F;package-summary.html&quot;&gt;java.lang.foreign&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;Explanation&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul class=&quot;explanation&quot;&gt;
&lt;li&gt;Incubator Phase: The initial steps of the FFM API were as incubating features, meaning they were experimental and subject to change. These releases introduced the core concepts like memory access and foreign function invocation. JEP 434 mentions that the FFM API was in its incubator phase in JDK 17 and JDK 18.&lt;&#x2F;li&gt;
&lt;br&gt;
&lt;li&gt;Preview Phase: In the preview phase, the API&#x27;s design and implementation were complete, but still subject to potential changes based on user feedback. OpenJDK JEP 424 describes the Foreign Function &amp; Memory API as a preview API in JDK 19.&lt;&#x2F;li&gt;
&lt;br&gt;
&lt;li&gt;Finalized: In JDK 22, the FFM API was declared stable and ready for production use, removing the need for preview flags and providing a more robust and reliable native interoperability solution.&lt;&#x2F;li&gt;
&lt;br&gt;
&lt;li&gt;Key Enhancements: This section highlights the significant changes and refinements introduced in each version of the FFM API as it evolved.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;memo-walking-through-ffmreceiver-a-first-taste-of-java-ffm-ai-generated&quot;&gt;📝 Walking Through FfmReceiver — A First Taste of Java FFM (&lt;em&gt;AI generated&lt;&#x2F;em&gt;)&lt;&#x2F;h3&gt;
&lt;p&gt;In this demo, we’re calling native io_uring functions in C from Java, to build a &lt;strong&gt;high-performance TCP receiver&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;Arena&lt;&#x2F;code&gt; — Memory Lifetime Manager&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-keyword z-control z-exception z-try z-java&quot;&gt;try&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Arena&lt;&#x2F;span&gt; arena &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;Arena&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;ofShared&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-java&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-meta z-block z-java&quot;&gt;    &lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-meta z-block z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-java&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Arena&lt;&#x2F;strong&gt; is a memory allocator with automatic cleanup.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Think of it as a &lt;strong&gt;“scope for native memory”&lt;&#x2F;strong&gt;: allocate native buffers inside it, and when the &lt;code&gt;try&lt;&#x2F;code&gt; block exits, the arena frees them automatically.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Variants:&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Arena Type&lt;&#x2F;th&gt;&lt;th&gt;Bounded Lifetime&lt;&#x2F;th&gt;&lt;th&gt;Manual Close (arena.close())&lt;&#x2F;th&gt;&lt;th&gt;Thread Access&lt;&#x2F;th&gt;&lt;th&gt;Common Use Case&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Global&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;No&lt;&#x2F;td&gt;&lt;td&gt;Yes (accessible by any thread)&lt;&#x2F;td&gt;&lt;td&gt;For memory that needs to persist for the entire lifetime of the application.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Automatic&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;No (managed by Garbage Collector)&lt;&#x2F;td&gt;&lt;td&gt;Yes (accessible by any thread)&lt;&#x2F;td&gt;&lt;td&gt;Simplest memory management for bounded lifetimes. The memory is deallocated when the arena becomes unreachable by the garbage collector.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Confined&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes (mandatory)&lt;&#x2F;td&gt;&lt;td&gt;No (only by the creating thread)&lt;&#x2F;td&gt;&lt;td&gt;Perfect for single-threaded applications. Provides deterministic deallocation of memory when the arena is closed, often used with try-with-resources.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Shared&lt;&#x2F;td&gt;&lt;td&gt;Yes&lt;&#x2F;td&gt;&lt;td&gt;Yes (mandatory)&lt;&#x2F;td&gt;&lt;td&gt;Yes (accessible by multiple threads)&lt;&#x2F;td&gt;&lt;td&gt;For concurrent applications where memory segments must be shared between threads. Closing the arena is safe and atomic, even when accessed by multiple threads.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Here we use &lt;code&gt;ofShared()&lt;&#x2F;code&gt; because multiple native calls may work with the allocated memory.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;SymbolLookup&lt;&#x2F;code&gt; — Finding Functions in a Shared Library&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;SymbolLookup&lt;&#x2F;span&gt; lib &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;SymbolLookup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;libraryLookup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-java&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;.&#x2F;libiouring_tcpa.so&lt;span class=&quot;z-punctuation z-definition z-string z-end z-java&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; arena&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SymbolLookup&lt;&#x2F;code&gt; is how Java finds functions or variables inside a native shared library (&lt;code&gt;.so&lt;&#x2F;code&gt;, &lt;code&gt;.dll&lt;&#x2F;code&gt;, &lt;code&gt;.dylib&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;You pass the library name and a scope (&lt;code&gt;arena&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Later, we’ll do &lt;code&gt;lib.find(&quot;io_uring_listen&quot;)&lt;&#x2F;code&gt; to grab the raw address of that function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;👉 Without &lt;code&gt;SymbolLookup&lt;&#x2F;code&gt;, Java wouldn’t know &lt;em&gt;where in memory&lt;&#x2F;em&gt; the C function lives.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;3. &lt;code&gt;Linker&lt;&#x2F;code&gt; — Bridging Java ↔ Native&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Linker&lt;&#x2F;span&gt; linker &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;Linker&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;nativeLinker&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linker&lt;&#x2F;strong&gt; builds a bridge between Java and C functions.&lt;&#x2F;li&gt;
&lt;li&gt;It knows how to:
&lt;ul&gt;
&lt;li&gt;Translate Java values to C values (e.g., &lt;code&gt;int&lt;&#x2F;code&gt; ↔ &lt;code&gt;int32_t&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Call into native functions and return values back&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;code&gt;nativeLinker()&lt;&#x2F;code&gt; automatically picks the system ABI (x86_64, ARM64, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;4. &lt;code&gt;MemorySegment&lt;&#x2F;code&gt; — Safe, Structured Native Memory&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;MemorySegment&lt;&#x2F;span&gt; buffer &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; arena&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;allocate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;bufferSize&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MemorySegment&lt;&#x2F;strong&gt; is a safe view of native memory.&lt;&#x2F;li&gt;
&lt;li&gt;Unlike &lt;code&gt;ByteBuffer&lt;&#x2F;code&gt; (which is limited and unsafe), a &lt;code&gt;MemorySegment&lt;&#x2F;code&gt; tracks bounds, lifetime, and thread access.&lt;&#x2F;li&gt;
&lt;li&gt;Example:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;byte&lt;&#x2F;span&gt; b &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; buffer&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_BYTE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; offset&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-java&quot;&gt;buffer&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_BYTE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; offset&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-java&quot;&gt;42&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Here, we allocate an &lt;strong&gt;8 MB receive buffer&lt;&#x2F;strong&gt; per client.&lt;&#x2F;li&gt;
&lt;li&gt;Later, we copy received bytes into a Java &lt;code&gt;byte[]&lt;&#x2F;code&gt; for debugging.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;5. &lt;code&gt;MethodHandle&lt;&#x2F;code&gt; — Calling Native Functions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Every native function we call has 3 steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Find its address&lt;&#x2F;strong&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;MemorySegment&lt;&#x2F;span&gt; addr &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; lib&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-java&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;io_uring_global_init&lt;span class=&quot;z-punctuation z-definition z-string z-end z-java&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;Describe its signature&lt;&#x2F;strong&gt; using &lt;code&gt;FunctionDescriptor&lt;&#x2F;code&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;FunctionDescriptor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;of&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_INT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_INT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;→ “returns int, takes an int argument”&lt;&#x2F;p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Bind with a&lt;&#x2F;strong&gt; &lt;code&gt;MethodHandle&lt;&#x2F;code&gt;:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;MethodHandle&lt;&#x2F;span&gt; mhGlobalInit &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; linker&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;downcallHandle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;globalInitAddr&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; descriptor&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;Call it&lt;&#x2F;strong&gt; like a Java method:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt; ret &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; mhGlobalInit&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;queueDepth&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;👉 A &lt;code&gt;MethodHandle&lt;&#x2F;code&gt; is like a strongly-typed function pointer.&lt;&#x2F;p&gt;
&lt;p&gt;It hides the messy details of JNI — no boilerplate, no unsafe casts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;6. &lt;code&gt;ValueLayout&lt;&#x2F;code&gt; — Mapping Java ↔ C Types&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ValueLayout&lt;&#x2F;code&gt; tells the FFM API how Java types map to C types.&lt;&#x2F;li&gt;
&lt;li&gt;Examples:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Java_INT&lt;&#x2F;code&gt; → C &lt;code&gt;int32_t&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Java_LONG&lt;&#x2F;code&gt; → C &lt;code&gt;int64_t&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Java_BYTE&lt;&#x2F;code&gt; → C &lt;code&gt;int8_t&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ADDRESS&lt;&#x2F;code&gt; → C pointers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So when we say:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;FunctionDescriptor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;of&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_INT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_INT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-java&quot;&gt;ADDRESS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-java&quot;&gt;ValueLayout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-java&quot;&gt;Java_LONG&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We mean:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c&quot; class=&quot;language-c z-code&quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;io_uring_recv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;clientFd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-c&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-c&quot;&gt;long&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;7. Putting It All Together&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the demo flow:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize io_uring&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;mhGlobalInit&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;queueDepth&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Create a TCP server socket&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt; listenFd &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; mhListen&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;port&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; backlog&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Accept connections&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt; clientFd &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; mhAccept&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;listenFd&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Receive data into a native buffer&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt; bytesReceived &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-parens z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; mhRecv&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;clientFd&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; buffer&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; bufferSize&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Inspect data in Java (first 128 bytes)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;&lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-array z-java&quot;&gt;[]&lt;&#x2F;span&gt; arr &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-instantiation z-java&quot;&gt;&lt;span class=&quot;z-keyword z-other z-storage z-new z-java&quot;&gt;new&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-primitive z-java&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-array-initialization z-java&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-java&quot;&gt;[&lt;&#x2F;span&gt;displayLen&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-java&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-java&quot;&gt;arr[i] &lt;span class=&quot;z-meta z-assignment z-rhs z-java&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-java&quot;&gt;=&lt;&#x2F;span&gt; buffer&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-java&quot;&gt;BYTE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-comma z-java&quot;&gt;,&lt;&#x2F;span&gt; i&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Close the socket&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;java&quot; class=&quot;language-java z-code&quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;z-source z-java&quot;&gt;mhClose&lt;span class=&quot;z-punctuation z-accessor z-dot z-java&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-java&quot;&gt;&lt;span class=&quot;z-variable z-function z-java&quot;&gt;invokeExact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-java&quot;&gt;(&lt;&#x2F;span&gt;clientFd&lt;span class=&quot;z-punctuation z-section z-parens z-end z-java&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-java&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;8. Why This Matters&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Traditionally, Java needed &lt;strong&gt;JNI&lt;&#x2F;strong&gt; for native calls — painful, verbose, unsafe.&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;strong&gt;FFM&lt;&#x2F;strong&gt;, we now have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Memory safety&lt;&#x2F;strong&gt; (bounds checks, lifetime control)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Performance&lt;&#x2F;strong&gt; (zero-copy native memory access)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Clarity&lt;&#x2F;strong&gt; (call native functions like Java methods)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Portability&lt;&#x2F;strong&gt; (same code runs across OS&#x2F;CPU with correct ABI handling)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This demo shows: &lt;strong&gt;pure Java controlling a high-performance Linux feature (io_uring)&lt;&#x2F;strong&gt; — something unimaginable&#x2F;complex with old JNI boilerplate.&lt;&#x2F;p&gt;
</content>
        <summary type="html">Sharing my initial learnings using Java FFM, Foreign Function &amp; Memory Access.</summary>
        </entry><entry xml:lang="en">
        <title>A Console Routine on Channeling NATS. Let&#x27;s GO!</title>
        <published>2025-04-05T00:00:00+00:00</published>
        <updated>2025-04-05T00:00:00+00:00</updated>
        <author>
            <name>Rohan Ray</name>
        </author>
        <link rel="alternate" href="https://www.roray.dev/blog/golang-nats/" type="text/html"/>
        <id>https://www.roray.dev/blog/golang-nats/</id>
        
            <content type="html">&lt;h1 id=&quot;tl-dr&quot;&gt;TL;DR&lt;&#x2F;h1&gt;
&lt;p&gt;This article is a short example of &lt;a href=&quot;https:&#x2F;&#x2F;nats.io&#x2F;&quot;&gt;NATS&lt;&#x2F;a&gt; - an open source messaging system, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rivo&#x2F;tview&quot;&gt;TVIEW&lt;&#x2F;a&gt; - Golang based Terminal UI library, concurrency in Golang using Channels and Goroutines. The source code can be found on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rohanray&#x2F;roray-dev-site&#x2F;tree&#x2F;main&#x2F;code&#x2F;nats-tview&quot;&gt;Github&lt;&#x2F;a&gt;.
&lt;br&gt;
&lt;br&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what&quot;&gt;What&lt;&#x2F;h1&gt;
&lt;p&gt;I have recently started working on a personal Golang project to develop something similar to &lt;a href=&quot;https:&#x2F;&#x2F;uptime.kuma.pet&#x2F;&quot;&gt;Uptime Kuma&lt;&#x2F;a&gt; which is a self-hosted monitoring tool. I believe it’s a perfect project with the right complexity to learn advanced concepts of Go.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;channel-nats.gif&quot; alt=&quot;Short video showcasing nats and golang channels with goroutines&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The project code in &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rohanray&#x2F;roray-dev-site&#x2F;tree&#x2F;main&#x2F;code&#x2F;nats-tview&quot;&gt;Github&lt;&#x2F;a&gt; has 4 directories:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Server&lt;&#x2F;strong&gt; - The central server which stores servers &amp;amp; resource details, configs etc&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Client&lt;&#x2F;strong&gt; - TUI based native client app to manage resources that need to be monitored. Also gives TUI based views into historical&#x2F;real-time monitoring data.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;&#x2F;strong&gt; - Remote light-weight agent running on target host servers responsible for shipping telemetry data to the central server&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Proto&lt;&#x2F;strong&gt; - &lt;a href=&quot;https:&#x2F;&#x2F;protobuf.dev&#x2F;&quot;&gt;Protobuf&lt;&#x2F;a&gt; based API contracts between server, client &amp;amp; agent.
&lt;br&gt;
&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;nats&quot;&gt;NATS&lt;&#x2F;h2&gt;
&lt;p&gt;NATS is a simple, secure and performant communications system and data layer for digital systems, services and devices. It’s used in this example project for pub-sub messaging (shipping) telemetry data from target remote servers to the central server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-nats-server&quot;&gt;The NATS server&lt;&#x2F;h3&gt;
&lt;p&gt;To keep things simple for this example, we are using an embedded NATS server which is setup in the central server as below:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;server&#x2F;main.go&quot; class=&quot;language-server&#x2F;main.go z-code&quot;&gt;&lt;code class=&quot;language-server&#x2F;main.go&quot; data-lang=&quot;server&#x2F;main.go&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;opts := &amp;amp;natsServer.Options{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		Port: 4222,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ns, err := natsServer.NewServer(opts)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;if err != nil {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    log.Fatal(err)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;go ns.Start()
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Line #2&lt;&#x2F;em&gt;  denotes that the embedded NATS server should run on port 4222.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Line #8&lt;&#x2F;em&gt;  &lt;code&gt;go ns.Start()&lt;&#x2F;code&gt;  The go keyword creates a new goroutine, which is a lightweight thread managed by the Go runtime. Goroutines are a fundamental part of Go’s concurrency model.&lt;&#x2F;p&gt;
&lt;p&gt;When this line executes, &lt;code&gt;ns.Start()&lt;&#x2F;code&gt; runs concurrently with the rest of the program. The main execution doesn’t wait for this method to complete but continues immediately to the next line. Such pattern is commonly used when launching background services, servers, or long-running processes that need to operate independently of the main program flow.
&lt;br&gt;
&lt;br&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;publishing-nats-message&quot;&gt;Publishing NATS message&lt;&#x2F;h3&gt;
&lt;p&gt;Let’s look at the agent code&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;agent&#x2F;main.go&quot; class=&quot;language-agent&#x2F;main.go z-code&quot;&gt;&lt;code class=&quot;language-agent&#x2F;main.go&quot; data-lang=&quot;agent&#x2F;main.go&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func main() {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	nc, err := nats.Connect(&amp;quot;nats:&#x2F;&#x2F;127.0.0.1:4222&amp;quot;)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	if err != nil {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		log.Fatal(err)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	defer nc.Close()
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	log.Println(&amp;quot;Connected to NATS server at&amp;quot;, nc.ConnectedUrl())
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	for c := time.Tick(1 * time.Second); ; &amp;lt;-c {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		v, _ := mem.VirtualMemory()
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		cpuPercent, _ := cpu.Percent(0, false)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		diskUsage, _ := disk.Usage(&amp;quot;&#x2F;&amp;quot;)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		stats := &amp;amp;api.BaseStatsReply{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			Cpu:  &amp;amp;cpuPercent[0],
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			Mem:  &amp;amp;v.UsedPercent,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			Disk: &amp;amp;diskUsage.UsedPercent,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		msg, err := proto.Marshal(stats)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		if err != nil {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			log.Fatal(err)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		err = nc.Publish(&amp;quot;host.stats.1&amp;quot;, msg)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		if err != nil {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			log.Fatal(err)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		log.Printf(&amp;quot;Published message to NATS server, #%v&amp;quot;, stats)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Line 2&lt;&#x2F;strong&gt; &lt;code&gt;nats.Connect(&quot;nats:&#x2F;&#x2F;127.0.0.1:4222&quot;)&lt;&#x2F;code&gt; initializes client connection to the NATS server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Line 22&lt;&#x2F;strong&gt; &lt;code&gt;nc.Publish(&quot;host.stats.1&quot;, msg)&lt;&#x2F;code&gt; publishes a single Protobuf serialized message containing the host base stats viz. CPU utilization, Memory utilization &amp;amp; Disk Usage.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why&quot;&gt;Why&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;Learn advanced concepts in Golang with real-life projects&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;(Try to)&lt;&#x2F;em&gt; Build a better Golang based open-source alternative to https:&#x2F;&#x2F;uptime.kuma.pet&lt;&#x2F;li&gt;
&lt;li&gt;To pique my interest in terminal user interface (TUI)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        <summary type="html">Sharing my initial learnings using NATS, Golang Channels &amp; Tview.</summary>
        </entry>
</feed>
