 6 minutes
 
                            6 minutes 
                            From Spring Boot To Jakarta EE 11: How Payara Starter Eases The Transition
If you’ve been living in the Spring ecosystem, you’re used to fast project setup. Spring Initializr gives you a […]
 
 
                        Java 21 introduces the Foreign Function and Memory (FFM) API, which allows Java programs to interoperate with code and data outside the Java runtime. Java operates within a managed environment known as the Java Virtual Machine (JVM). The JVM serves as an abstraction layer between the executing Java code and the underlying hardware and OS. One of the core design principles behind the JVM is to provide a secure and isolated environment for Java applications to run. This isolation is beneficial for several reasons, including security and stability; it mitigates risks such as unauthorized access to system resources or memory corruption, which could lead to vulnerabilities like buffer overflows.
However, this isolation can sometimes be a limitation when Java applications need to interact with system-level resources or libraries written in other programming languages. For instance, you might have a performance-critical application that requires the speed of a native library written in C or C++. Or perhaps you’re working on an application that needs to interface with hardware devices directly, something that’s usually done via native libraries. In such cases, Java’s traditional approach has been to use the Java Native Interface (JNI). While powerful, JNI comes with its own set of complexities and risks, such as memory leaks and crashes, which can undermine the robustness of the Java application.
This is where Java 21’s Foreign Function and Memory (FFM) API comes into play. The FFM API allows Java programs to interoperate safely and more easily with code and data outside the Java runtime. Unlike JNI, which often involves brittle and error-prone boilerplate code, the FFM API aims to provide a more straightforward and safer method for calling native libraries and manipulating native data. This opens up new possibilities for Java applications, enabling them to leverage the performance or capabilities of native libraries without sacrificing the security and stability that come with the JVM’s isolated environment.
The following code shows calling the strlen function in C to determine the length of a Java String passed to it. Of course this is just an example to show how you can use the API to carry out such cross method calls.
public static void main(String[] args) throws Throwable {
 // This line creates a SymbolLookup object, which can be used to find native symbols on the C library path.
 SymbolLookup stdlib = Linker.nativeLinker().defaultLookup();
 // This line creates a MethodHandle object for the strlen() function. The MethodHandle object contains all
 // the information needed to call the native function, such as the function pointer and the function signature.
 MethodHandle strlen = Linker.nativeLinker().downcallHandle(
 stdlib.find("strlen").orElseThrow(),
 FunctionDescriptor.of(JAVA_LONG, ADDRESS));
 // This line creates an Arena object. An Arena is a region of memory that can be used to allocate off-heap
 // memory. The try-with-resources statement ensures that the Arena object is automatically closed when the code
 // block exits.
 try (Arena offHeap = Arena.ofConfined()) {
 // This line allocates a region of off-heap memory to store the string "Java 21 rocks! Yay!!!". The
 // MemorySegment object represents the allocated off-heap memory.
 MemorySegment str = offHeap.allocateUtf8String("Java 21 is the issh");
 // This line calls the strlen() function to calculate the length of the string "Java 21 works". The strlen()
 // function takes a pointer to a string as input and returns the length of the string as output.
 long len = (long) strlen.invoke(str);
 System.out.println("len = " + len);
 }
 }
This example shows how to load a native library, get a function pointer, allocate memory for the function arguments, set the function arguments, call the native function, and get the result.
The FFM API also provides a number of other features, such as:
As you can see, the FFM API is a powerful tool that can be used to write Java programs that interact with code and data outside the Java runtime. It is a safe, efficient, and easy-to-use alternative to JNI. Some situations where you might want to use this API are:
Examples of specific situations where you might want to use the FFM API:
If you are writing a Java program that needs to interact with native code, the FFM API is a good option to consider. It is a safe, efficient, and portable way to call native functions and access native data.
Enjoyed this article? See more of our Java 21 content:
And remember, we have launched our own fully-managed cloud native application runtime, Payara Cloud.
Fully managed Jakarta EE Deployment. ✅Handles Kubernetes for you.✅ 15 day free trial available.✅
Payara Cloud.
Share:
 6 minutes
 
                            6 minutes 
                            If you’ve been living in the Spring ecosystem, you’re used to fast project setup. Spring Initializr gives you a […]
 2 minutes
 
                            2 minutes 
                            How outdated Java systems are draining budgets and throttling innovation across financial services? Let’s dig in in this blog […]
 3 minutes
 
                            3 minutes 
                            Exploring the Future of AI with the Jakarta EE Community At Payara, we’re passionate about pushing the boundaries of […]
Please re-wrap your code comments so they don’t get lost to vagaries of the browser.