me • Takaaki Sugiyama • @zinbe / @zinbe.bsky.social • Software Engineer • Technical Writer / Author • Board member of Japan Java User Group (JJUG) • Director of CCC Association JCConf 2025: Building a Community for Developer to Connect →
T S ID E The "outside world" = beyond the JVM • “Write Once, Run Anywhere” — Java's original promise • Anything platform-specific is hidden beneath the JVM abstraction • Everything past that boundary is the "outside world" Java application JVM “Hiding” was Java's strength OS · CPU · hardware hidden below this line Outside
Native Interface • An API for calling native code (C/C++) from Java — and Java from native code • Gives Java access to OS-specific features • Serial ports, for example • Has been part of Java since 1.1 (1997)
with Java and Arduino — JNI Main Java Program C header file Interface for serial communication C native library Wrapper class for C function OS system call Arduino sketch
communication SerialPort.java public class SerialPort implements AutoCloseable { private final SerialPortNative nativePort; private final int fd; public SerialPort(String portName) throws Exception { this.nativePort = new SerialPortNative(); this.fd = nativePort.openPort(portName); } public void sendCommand(char command) { byte[] data = new byte[] { (byte) command }; nativePort.writeData(fd, data, 1); } public void close() { nativePort.closePort(fd); } } Port open Write some data Port close
T S ID E Why so complex? I can't remember who it was, but I was talking to one of the engineers back in the Sun days and expressing my frustration with JNI being hard to use. That's when he said it had been developed that way to encourage people NOT to use it… — Simon Ritter, Deputy CTO of Azul Hard to use — by design, not by accident
T S ID E The times changed What's out there now Native Libraries SIMD GPU · TPU · FPGA A vast body of existing code — image processing, machine learning, cryptography, numerical computing The CPU's own instructions. AVX-512 processes 16 floats at once Parallel computation is no longer a specialist niche Not being able to use them stopped being the price of safety.
T S ID E The path Java chose 1 Hide it beneath an abstraction 2 Hand it off to another language 3 Make the outside world expressible in Java You sacrifice both performance and expressiveness The JNI world. The complexity stays The path Java chose
T S ID E The map of this session The outside world Java's answer What became in Java Native code and memory FFM API Memory and function calls The CPU's SIMD instructions Vector API Vector arithmetic GPUs and accelerators Project Babylon Code itself
for working with native memory and native functions from Java, safely and efficiently • Released in Java 22 (March 2024) • An output of OpenJDK Project Panama Goals • Replace JNI with something usable • Reduce overhead • Manage native memory safely
managing the lifetime of memory • An Arena has a scope, and every segment allocated from it is tied to that scope • When memory is released, and which threads may access it, are both decided by the Arena • Four kinds: Global / Automatic / Confined / Shared try (Arena arena = Arena.ofConfined()) { // All memory allocated // here becomes // inaccessible once the // scope is left }
a region of native memory // Allocate memory MemorySegment segment = arena.allocate(100); // Write data segment.set(ValueLayout.JAVA_INT, 0, 42); segment.set(ValueLayout.JAVA_BYTE, 4, (byte) 5); // Read data int value = segment.get(ValueLayout.JAVA_INT, 0); • Out-of-bounds access throws an exception • Once the Arena is closed, the segment becomes inaccessible automatically In C these are segfaults — or worse, code that appears to work
the shape of data in memory C Java struct Point { int x; int y; }; StructLayout pointLayout = MemoryLayout.structLayout( ValueLayout.JAVA_INT.withName("x"), ValueLayout.JAVA_INT.withName("y") ); • ValueLayout — primitives (JAVA_INT, JAVA_LONG, …) • StructLayout — structs • SequenceLayout — a repetition of the same layout
the Foreign Function API • SymbolLookup: Finds a function's address in a library • defaultLookup(): Search the standard C library (libc) • libraryLookup(): Search the library at the specified path • loaderLookup(): Search for a library loaded via System.loadLibrary() • Linker: Turns the native function address into a MethodHandle • downcallHandle(): Native function call from Java • upcallStub(): Pass a callback function to native code • FunctionDescriptor: Define the signature information for native functions.
• Generates Java bindings mechanically from a C header file • Another output of Project Panama • Currently an early-access build, installed separately jextract --output classes -t org.unix /usr/include/string.h ↓ public static long strlen(MemorySegment __s) { ...... } long length = (long) org.unix.string_h.strlen(str);
Another example: Raspberry Pi • Direct hardware control via GPIO • Calling the C library libgpiod through the FFM API Pi4J V4 · February 2026 • The standard library for GPIO, I2C, SPI and PWM from Java • V4 moved to Java 25 and added an FFM API plugin • Native libraries are the heart of Pi4J — and that heart is now FFM Providers are pluggable PiGpio JNI-based GpioD libgpiod-based LinuxFS Linux filesystem-based FFM FFM API-based
API really safe? You get some warnings when running it • JEP draft: Integrity by Default - Disable or warn by default for unsafe features • Some FFM API methods are inherently unsafe • Linker.downcallHandle, SymbolLookup.libraryLookup, … • JNI, sun.misc.Unsafe, some parts of reflection are also unsafe Going outside requires explicit permission
world Java's answer What became in Java Native code and memory FFM API Memory and function calls The CPU's SIMD instructions Vector API Vector arithmetic GPUs and accelerators Project Babylon Code itself
Scalar a[0]+b[0] → a[1]+b[1] → a[2]+b[2] → a[3]+b[3] 4 operations SIMD a[0..3] + b[0..3] 1 operation SSE AVX AVX-512 ARM SVE 4 floats 8 floats 16 floats up to 16 The CPU always had this. Java just had no explicit way to use it
Compile to SIMD instructions on CPUs at run time Core concepts VectorSpecies Vector<E> A combination of element type and vector length. FloatVector.SPECIES_PREFERRED picks the best one for the runtime environment A fixed-length sequence of elements: FloatVector, IntVector, DoubleVector, ByteVector, … Lane VectorMask The position of each element within a vector Controls, per lane, whether the operation applies
does auto-vectorize. However — • The JIT analyses loops and converts them to SIMD instructions automatically • But there is no guarantee about when it kicks in • Results vary with how the loop is written, the JVM version, and the CPU • Complex algorithms are never recognised in the first place • Vectorized hashCode, specialised array comparisons, and so on “it'll probably be faster” → “it will be faster”
Scalar Vector API float sum = 0f; for (int i = 0; i < a.length; i++) { sum += a[i] * b[i]; } static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED; FloatVector vsum = FloatVector.zero(SPECIES); int upperBound = SPECIES.loopBound(a.length); for (int i = 0; i < upperBound; i += SPECIES.length()) { var va = FloatVector.fromArray(SPECIES, a, i); var vb = FloatVector.fromArray(SPECIES, b, i); vsum = va.fma(vb, vsum); // vsum += va * vb } float sum = vsum.reduceLanes(VectorOperators.ADD); // tail elements handled separately It is longer to write. In exchange, you get the instructions as you write.
Anywhere the same operation repeats over a lot of data • Machine learning • Image processing • Linear algebra • Cryptography • Financial computation • The JDK’s own internals
• Introduced in JDK 16 (March 2021) • JEP 529 in JDK 26 as the Eleventh Incubator • JDK 27 has JEP 537 planned — The Twelfth Incubator • Requires --add-modules jdk.incubator.vector The Vector API will incubate until Value Objects (the features of Project Valhalla) become available as preview features. JEP 401: Value Objects (Preview) is targeted in JDK 28 (planned for March 2027)
The scalar version for (int px = 0; px < width; px++) { float cx = cxs[px]; float x = 0f, y = 0f; int iter = 0; while (x * x + y * y <= 4f && iter < maxIter) { float xt = x * x - y * y + cx; y = (x * y) * 2f + cy; x = xt; iter++; } iters[px] = iter; } How many times this loop runs depends on the data • Every pixel escapes at a different iteration • The JIT cannot know the trip count in advance • Exactly the case autovectorization does not handle
The vector version: the shape for (int px = 0; px < width; px += SPECIES.length()) { FloatVector cx = FloatVector.fromArray(SPECIES, cxs, px); FloatVector cy = FloatVector.broadcast(SPECIES, cyScalar); FloatVector x = FloatVector.zero(SPECIES); FloatVector y = FloatVector.zero(SPECIES); FloatVector iter = FloatVector.zero(SPECIES); for (int i = 0; i < maxIter; i++) { // the same arithmetic, on whole vectors // + three lines that do the real work } iter.intoArray(iterCounts, px); } • The outer loop advances by SPECIES.length() pixels at a time • The while became a for — a fixed count, up to maxIter • “When does this pixel stop?” moves out of the loop condition
The numbers Time Speedup Scalar 2685 ms 1.0× Vector API / ARM NEON – 4 lanes 775 ms 3.46× Vector API / AVX-512 – 16 lanes 288 ms 9.32× Why isn't the speedup equal to the lane count? Lanes that escape early still run until the last lane in their group finishes. You pay for the slowest pixel in every group. Isn't this just parallelism? No — one thread, one core. SIMD is width, not thread count. And the two compose.
revisited The outside world Java's answer What became in Java Native code and memory FFM API Memory and function calls The CPU's SIMD instructions Vector API Vector arithmetic GPUs and accelerators Project Babylon Code itself
is Project Babylon • A project to extend Java's reach to “foreign programming models” • GPUs, machine learning models, SQL, differentiable programming Code Model Code Reflection API A symbolic representation of code, generated by the compiler, at a higher level than bytecode An API for accessing, manipulating and transforming the Code Model at runtime Not a JEP yet — the priority is getting code reflection designed correctly
about Code Reflection @CodeReflection static float compute(float a, float b) { return a * b + 1.0f; } • Traditional reflection: inspects the structure — classes, methods, fields • Code Reflection: extracts the meaning of a computation as a symbolic representation Bytecode Code Model “how to execute it” “what is being computed”
Heterogeneous Accelerator Toolkit Java → Code Model → GPU driver binary • Backends: OpenCL C, CUDA PTX (SPIR-V in development) • NDRange API (thread configuration), iFaceMapper (memory layout), Accelerator (device selection) No C No separate kernel source files No JNI
just GPUs GPU execution Generative AI inference HAT ONNX models running inside Java Automatic differentiation Query translation Training neural networks Something like C#'s LINQ, in Java Still experimental — try it today with --add-modules jdk.incubator.code
answer What became in Java Status Native code and memory FFM API Memory and function calls Final in Java 22 The CPU's SIMD instructions Vector API Vector arithmetic Incubator, waiting on Valhalla GPUs and accelerators Project Babylon Code itself Experimental, pre-JEP Only the FFM API is finished. We are partway there.
about the outside world in its own language FFM API Native interop in Java has fundamentally changed. The ecosystem is moving too, as Pi4J V4 shows. Vector API Makes the CPU's capabilities explicitly available from Java. Progress on Valhalla may change the situation. Project Babylon Trying to widen the reach of Java itself. We’re halfway there. It's going to keep getting better.
454: Foreign Function & Memory API — https://openjdk.org/jeps/454 • JEP 472: Prepare to Restrict the Use of JNI — https://openjdk.org/jeps/472 • JEP 529: Vector API (Eleventh Incubator) — https://openjdk.org/jeps/529 • JEP 401: Value Objects (Preview) — https://openjdk.org/jeps/401 • JEP draft: Integrity by Default — https://openjdk.org/jeps/8305968 • Project Babylon — https://openjdk.org/projects/babylon/ • jextract — https://jdk.java.net/jextract/ • Pi4J — https://www.pi4j.com/