Language Avançado

FFM permite que o Java chame bibliotecas C diretamente, sem boilerplate de JNI ou conhecimento de Java no lado C.

✕ Java 1.1+
public class CallCFromJava {
    static { System.loadLibrary("strlen-jni"); }
    public static native long strlen(String s);
    public static void main(String[] args) {
        long ret = strlen("Bambi");
        System.out.println("Return value " + ret); // 5
    }
}

// Run javac -h to generate the .h file, then write C:
// #include "CallCFromJava.h"
// #include <string.h>
// JNIEXPORT jlong JNICALL Java_CallCFromJava_strlen(
//     JNIEnv *env, jclass clazz, jstring str) {
//     const char* s = (*env)->GetStringUTFChars(env, str, NULL);
//     jlong len = (jlong) strlen(s);
//     (*env)->ReleaseStringUTFChars(env, str, s);
//     return len;
// }
✓ Java 22+
void main() throws Throwable {
    try (var arena = Arena.ofConfined()) {
        // Use any system library directly — no C wrapper needed
        var stdlib = Linker.nativeLinker().defaultLookup();
        var foreignFuncAddr = stdlib.find("strlen").orElseThrow();
        var strlenSig = FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
        var strlenMethod = Linker.nativeLinker() .downcallHandle(foreignFuncAddr, strlenSig);
        var ret = (long) strlenMethod.invokeExact(arena.allocateFrom("Bambi"));
        System.out.println("Return value " + ret); // 5
    }
}

// Your own C library needs no special Java annotations:
// long greet(char* name) {
//     printf("Hello %s\n", name);
//     return 0;
// }
Viu um problema com este código? Nos avise.
👁

Código C permanece C puro

A função C não requer anotações JNI ou boilerplate JNIEnv — qualquer biblioteca C existente pode ser chamada como está.

Mais flexível

Chame diretamente a maioria das bibliotecas C/C++ existentes sem escrever código adaptador ou gerar arquivos de cabeçalho.

🛠️

Fluxo de trabalho mais simples

Sem necessidade de parar, executar javac -h e implementar a interface definida no arquivo .h gerado.

Abordagem Antiga
JNI (Java Native Interface)
Abordagem Moderna
FFM (Foreign Function & Memory API)
Desde o JDK
22
Dificuldade
Avançado
Chamar código C a partir do Java
Disponível

Padronizado no JDK 22 (março de 2024); anteriormente em incubação desde o JDK 14

O Java possui duas abordagens para chamar código nativo C/C++: o tradicional JNI e a moderna API FFM. Com o JNI, você declara um método como native, executa javac -h para gerar um arquivo de cabeçalho C e implementa a função usando a complicada API JNI de C (JNIEnv, jstring, etc.). O FFM, introduzido como API padrão no Java 22, elimina tudo isso: o código C é C puro — sem convenções JNI necessárias. Isso torna muito mais fácil chamar bibliotecas C/C++ existentes sem modificações. O lado Java usa Arena para o gerenciamento seguro de memória fora do heap e MethodHandle para o downcall, garantindo flexibilidade e segurança.