Unsafe is Finally Going Away: Embracing Safer Memory Access with JEP 471

Java’s sun.misc.Unsafe is being phased out. Learn safer memory access using VarHandle and Foreign Function & Memory API to keep your applications secure and up-to-date.

Exploring New Features in JDK 23: Simplifying Java with Primitive Type Patterns with JEP 455

Java continues to evolve, introducing features that streamline coding practices and improve readability. JEP 455 is one such proposal that enhances the switch statement, making it more versatile and expressive. This article delves into how JEP 455 can be utilized to handle complex decision-making scenarios more efficiently. We’ll examine a practical example to illustrate the … Read more

Exploring New Features in JDK 23: A Sneak Peek

The main method and println With JDK 23 on the horizon, I decided to dive into some of its new features by running the following code in the CLI: void main() { println(“Hello World”); var name = readln(“Enter your name: “); println(“Your name is ” + name); var age = readln(“Enter your age: “); println(“Your … Read more

Records for Cleaner and More Expressive Parameterized Tests in JUnit 5

Introduction:Β  Parameterized testing in JUnit 5 is a potent technique for executing the same test logic with various inputs. While you can use a variety of data structures, such as custom classes, arrays, or collections, Java records offer a compelling advantage in readability, type safety, and expressiveness. Let’s examine how to leverage Java records for … Read more

Homecoming Chronicles: Navigating Parenting, Flights, and New Beginnings

Toronto usually blanketed in snow,Β  hasn’t seen much this winter yetβ€”El Nino effect. I was a bit surprised as well. Amidst this, I realized it’s been ages since my last newsletter.Β  A lot of events unfolded in the interim. The biggest thing? I went back to my homeland with my little baby girl, who is … Read more

Accessing Native C Functions from Java Using OpenJDK’s JEP 454: Foreign Function & Memory API

Introduction

Java’s robustness and cross-platform capabilities have made it a staple in enterprise applications. However, there are scenarios where Java applications need to interact with native libraries written in languages like C or C++. The Java Native Interface (JNI) has been the traditional solution for such needs, but it comes with its own complexities and performance overheads. OpenJDK’s JEP 454, aims to offer a more straightforward and efficient alternative. Part of Project Panama, this API is designed to improve Java’s capabilities for interacting with native code. In this article, we’ll walk through a simple example to demonstrate how to use JEP 454 to call a C function from a Java program.

It’s important to note that this JEP is still in preview mode. To experiment with it, you’ll need JDK 22. You can use SDKMan to install JDK 22 on your system easily.

What is in JEP 454?

Java Enhancement-Proposal (JEP) 454 aims to introduce a Foreign Function & Memory API that simplifies the interaction between Java and native code. The API consists of two main components:

  1. Foreign Function Interface (FFI): Enables Java programs to call native functions easily, abstracting much of the boilerplate code required in JNI.
  2. Memory Access API: Provides a set of tools for interacting with native memory, including features for memory allocation, deallocation, and manipulation of native data structures.

JEP 454 is designed to be highly performant and includes various safety checks to prevent common pitfalls like buffer overflows. It is intended to replace JNI for most use cases, offering a more efficient and safer way to access native libraries and manage native memory.

Creating the C Library

First, let’s create a C program that contains a simple function to add two integers. The code for this is as follows:

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

After writing the code, save it in a file namedΒ addition.c. To compile this into a shared library, navigate to the directory where the file is located and run the following command:

gcc -shared -o libaddition.so -fPIC addition.c

This command compiles the C code into a shared library namedΒ libaddition.so, ready to be accessed by our Java program.

Writing the Java Program

Next, let’s write a Java program that uses the Foreign Function & Memory API to call theΒ addΒ function from our C library. The Java code is as follows:

import java.lang.foreign.*;
import java.nio.file.Path;

public class Main {
    void main() {

        try (var arena = Arena.ofConfined()) {
            var lib = SymbolLookup.libraryLookup(Path.of("libaddition.so"), arena);
            var linker = Linker.nativeLinker();
            var fd = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT);
            var addFunc = lib.find("add").get();

            var methodHandle = linker.downcallHandle(addFunc, fd);
            var sum = methodHandle.invoke(1, 2);
            System.out.println("sum = " + sum);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

ReplaceΒ "libaddition.so"Β with the actual path to the compiled C library.

Running the Java Program

To compile and run the Java program, use the following command:

java --source 22 --enable-preview Main.java

If everything is set up correctly, the output should display:

sum = 3

Conclusion

OpenJDK’s JEP 454 offers a promising alternative to JNI for interacting with native code. By providing a simpler, safer, and more efficient API, it has the potential to revolutionize how Java developers work with native libraries and memory.

How to Diagnose and Mitigate Pinning in Java’s Virtual Thread Execution

In the context of virtual threads, pinning refers to the condition where a virtual thread is “stuck” to its carrier thread (the platform thread on which it runs).

What is a semaphore, and when to use it?

In Java’s concurrency API, a semaphore is another synchronization tool that simultaneously controls the number of threads accessing a particular resource or section of code. It manages a set of permits; threads must acquire a permit before proceeding. If a permit is available, the thread acquires it and continues execution. If not, the thread is … Read more

What is CyclicBarrier and When to Use It in Java?

In Java’s concurrency API, CyclicBarrier is another kind of synchronizer, similar to CountDownLatch. It enables multiple threads to wait for each other at a predefined execution point before resuming work. For example, consider a financial application that performs complex risk assessments for various portfolios. The reviews could involve multiple steps like data gathering, calculations and … Read more

What is CountDownLatch and How to Use It?

In Java’s concurrency API, CountDownLatch is a synchronizer that allows one or more threads to wait for a set of operations to complete. Imagine you’re developing a server application that relies on various resources to be initialized before it can start processing requests. These resources could be things like: Loading configuration files Establishing database connections … Read more