Learn · concepts

What Is JNI? Java Native Interface for Modders

JNI (Java Native Interface) is Java's built-in bridge for calling C/C++ from the JVM and back. It is the standard way a Minecraft mod loads a native library.

TRtrol5 min read

What is JNI in plain terms?

JNI (Java Native Interface) is the part of Java that connects two worlds: managed bytecode on the JVM and compiled machine code written in C or C++. A method gets the native keyword and no body, and at runtime the JVM links it to a matching function in a loaded native library. From there both sides trade arguments and return values.

The boundary is not one-directional. The native function receives a JNIEnv pointer, and that handle is the gateway back into Java: it exposes calls for reading and writing Java fields, invoking Java methods, constructing objects, and raising exceptions. So the same bridge that lets Java call out also lets C call in.

Why would a Minecraft mod or client touch native code?

Most Java never needs JNI. A mod reaches for it when the JVM alone cannot do the job, usually graphics, audio, OS integration, or a routine that has to be fast. The native library does the heavy lifting and JNI is the standard way to load and call it.

Reuse a proven C library

A mature native codebase already solves the problem. Rewriting it in Java is wasted effort, so the mod binds to it instead.

Reach the operating system

Some platform features have no pure-Java API. A native call becomes the only route to them.

Speed a hot path

A tight numeric or low-level routine can run faster as compiled native code than as bytecode on the JVM.

Drive hardware and drivers

Rendering, sound, and device access frequently sit behind native libraries that JNI exposes to the Java side.

How does a JNI call work end to end?

The flow is identical on every platform: declare the method in Java, compile a matching C function into a shared library, load it at runtime, let the JVM link them by name, then call across. Function names follow a fixed pattern so the JVM can resolve them, and a generated header spells out the exact signature to implement.

StepWhat happens
DeclareA Java method is written with the native keyword and left empty on the Java side.
BuildA C or C++ function is compiled into a shared library: .dll on Windows, .so on Linux, .dylib on macOS.
LoadJava calls System.loadLibrary to load that library while the program runs.
LinkThe JVM matches each native method to its C function by a name-mangled signature.
CallJava invokes the method; control crosses into native code and returns with a result.

What does JNI cost you?

JNI is powerful and it has sharp edges. Because native code runs outside the JVM's safety net, a fault there crashes the entire process rather than throwing a catchable exception. Memory the native side allocates is invisible to the garbage collector, so leaks pile up unless they are freed by hand. Each crossing carries overhead, which makes calling across the boundary inside a tight loop expensive. And native builds are platform-locked: a Windows .dll will not load on Linux without a separate compile.

What it buys

  • Direct access to existing C and C++ libraries
  • A path to OS and hardware features the JVM cannot reach
  • Native-speed execution for the hottest routines

What it costs

  • A native crash can take down the whole JVM
  • Manual memory management with no garbage-collector backstop
  • Per-platform builds to maintain and ship
  • Boundary-crossing overhead in hot loops

JNI vs the Foreign Function and Memory API

JNI is the original mechanism, but it is no longer the only one. Newer Java releases ship the Foreign Function and Memory (FFM) API, designed to call native code with less boilerplate and tighter safety guarantees. JNI still dominates existing toolchains because it is everywhere and thoroughly understood.

JNIFFM API
AgeOriginal, present since early JavaModern, added in recent releases
BoilerplateGenerated headers, name-mangled C functionsMethod handles defined in Java, no glue C
Memory safetyManual; mistakes can corrupt the JVMBounded segments with stronger checks
AdoptionUbiquitous across existing librariesGrowing, newer codebases

FAQ

Get Terminus

Built by people who actually read the JVM internals.