Timp de aproape trei decenii, interoperabilitatea dintre Java și codul nativ C/C++ s-a bazat pe bătrânul Java Native Interface (JNI). JNI era notoriu pentru complexitatea extremă (necesita scrierea și compilarea manuală de fișiere C intermediare de bridging), fragilitate și riscul ridicat de a prăbuși întregul proces JVM cu erori de tip Segfault.
Stabilizat în Java 22 ca parte a Project Panama, Foreign Function & Memory (FFM) API revoluționează acest domeniu, permițând codului Java să acceseze memorie nativă în afara heap-ului (Off-Heap) și să apeleze direct biblioteci dinamice externe (.so, .dll, .dylib) fără nicio linie de cod C intermediar!
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public class PanamaDemo {
public static void main(String[] args) throws Throwable {
// 1. Obținem linker-ul nativ corespunzător platformei hardware curente (x86_64 / ARM64):
Linker linker = Linker.nativeLinker();
// 2. Căutăm adresa funcției standard 'strlen' din biblioteca C de sistem (libc):
SymbolLookup stdlib = linker.defaultLookup();
MemorySegment strlenAddress = stdlib.find("strlen").orElseThrow();
// 3. Definim descriptorul semnăturii: returnează size_t (JAVA_LONG) și primește char* (ADDRESS):
FunctionDescriptor descriptor = FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
MethodHandle strlenHandle = linker.downcallHandle(strlenAddress, descriptor);
// 4. Gestiunea deterministă a memoriei Off-Heap prin Arena:
// Arena.ofConfined() garantează că memoria este eliberată AUTOMAT la închiderea blocului!
try (Arena arena = Arena.ofConfined()) {
// Alocăm un șir de caractere C nativ terminat cu null ('\0') direct în afara Heap-ului:
MemorySegment cString = arena.allocateFrom("DexBlog Invata Java Modern");
// Apelăm funcția nativă C direct din Java:
long lungime = (long) strlenHandle.invokeExact(cString);
System.out.println("Lungime calculată de funcția nativă C strlen: " + lungime);
} // Memoria fizică este dealocată instantaneu de sistem, fără a aștepta Garbage Collector-ul!
}
}
De Ce FFM API Este Superior Vechiului Bytebuffer direct?
- Siguranță Spațială și Temporală: Un
MemorySegmentnu poate fi accesat după ceArenas-a închis (elimină riscul de Use-After-Free) și aruncă excepții sigure la încercări de depășire de limită. - Performanță Extremă: Elimină costul de copiere a datelor între JVM și sistemul de operare la procesarea pachetelor de rețea sau a graficii 3D.