Skip to main content

02. Design philosophy

Why JNI and not GraalVM polyglot​

GraalVM's Polyglot API can call Java from a guest language but requires running on GraalVM, not stock HotSpot or OpenJ9. MEP-67 targets any compliant JVM. JNI has been part of the JVM specification since Java 1.1 and is supported on every JVM Mochi is likely to encounter in production: HotSpot (OpenJDK), Eclipse OpenJ9, GraalVM (which also supports JNI alongside its polyglot API), and Android's ART.

Why JNI and not JNA or JNR-FFI​

JNA and JNR-FFI load native libraries from Java. MEP-67 goes the other direction: loading the JVM from a Go/Mochi binary. JNA/JNR-FFI do not provide a path to embed a JVM inside a Go process. The libjvm shared library plus JNI Invocation API is the only standard mechanism for that embedding.

Why Java reflection over annotation databases​

Third-party annotation databases (typedefs repositories, manually curated JSON schemas) go stale and have incomplete coverage. Java reflection (java.lang.reflect) operates directly on the compiled bytecode shipped in the JAR: the output is exactly as accurate as what the end user's code sees. There is no coverage gap and no schema drift.

Why KindHandle for unmappable types​

Rather than refusing the entire class when one method uses an unmappable return type, MEP-67 assigns the KindHandle kind (backed by a long JNI global reference) to the return value. The caller can pass the handle back to other bridged methods that accept it as a parameter. This preserves the usability of classes that mix mappable and unmappable APIs. The 15 SkipReason constants log which methods are excluded and why, giving users a clear picture of the bridge surface.

Why the closed type table​

An open type table (attempt to map every Java type) risks silent semantic mismatches. The closed table (15 base types, explicit refusal set) makes the boundary legible: if a Java type is not in the table, it either gets KindHandle or a SkipReport. Users can audit the SkipReport to decide whether to add a hand-written shim.