java_interop library

Call Java from pure Dart over JNI, using only dart:ffi.

Boots a JVM in-process (or attaches to the one this process already has), loads jars from a class path, and calls constructors, methods, fields and arrays with full primitive coverage. Java throwables surface as Dart JavaExceptions.

final jvm = Jvm.startOrAttach(classPath: ['path/to/your.jar']);

final greeter = JavaClass.forName(jvm, 'com.nfeflash.example.Greeter');
final instance = greeter.newInstance('(Ljava/lang/String;)V', ['Dart']);

print(instance.call('greet', '()Ljava/lang/String;')); // Hello, Dart!
print(greeter.callStatic('add', '(II)I', [2, 40]));    // 42

instance.release();
greeter.release();

There are two layers. JavaClass / JavaObject / JavaArray read the signature string and dispatch, convert Dart arguments — a String to a jstring, a List to a Java array, a number to its wrapper — and release the temporaries that makes; they also cache the member ids they resolve. Use these. Underneath, extensions on Jvm (JvmClasses, JvmCalls, JvmFields, JvmArrays, JvmStrings) mirror the JNI C API one-to-one for the cases the high-level layer does not cover, and Jvm.fnSlot is the escape hatch for JNI functions this binding does not wrap at all.

One JVM per process. JNI_CreateJavaVM may be called once, and HotSpot cannot start another after Jvm.destroy. Jvm.startOrAttach therefore reuses an existing VM when it finds one — which is what makes this work under dart test, where every suite is a separate isolate in a shared process.

Classes

JavaArray
A Java array of elementDescriptor elements.
JavaClass
A resolved Java class.
JavaField
A parsed Java field declaration: int count, static String NAME.
JavaMethod
A parsed Java method declaration: the name, when one was given, and the signature.
JavaObject
An instance of a Java class.
JavaRef
A handle to a Java object.
JavaWrapper
One of the eight java.lang primitive wrapper classes.
JniFn
Slots in struct JNINativeInterface_, reached through JNIEnv*.
JniResult
Return codes from JNI_CreateJavaVM, GetEnv and friends.
JniSignature
A parsed JNI method signature.
JniType
The eight JNI primitive descriptors, plus void.
JniVersion
JNI_VERSION_1_6 from jni.h — the lowest version that supports everything bound here, so JniVersion.v1_6 is what JniVmFn.getEnv asks for.
JniVmFn
Slots in struct JNIInvokeInterface_, reached through JavaVM*.
JSig
A Java method signature, built from JTypes.
JType
A Java type, as the JNI descriptor that denotes it.
JValue
A single JNI argument, staged as the raw 64 bits of its jvalue slot.
Jvm
An embedded JVM.
LibjvmSearch
Where defaultLibjvmPath looked, in order, and what it found.

Enums

JavaRefKind
Whether a reference is local (thread- and frame-scoped) or global (valid until explicitly deleted, on any thread).

Extensions

JvmArrays on Jvm
Array creation and access.
JvmBoxing on Jvm
Boxing and unboxing primitives.
JvmCalls on Jvm
Invoking constructors and methods.
JvmClasses on Jvm
Looking up classes and their members.
JvmFields on Jvm
Field access.
JvmLocalFrames on Jvm
Scoped local-reference management.
JvmStrings on Jvm
String conversion.

Properties

classPathSeparator String
The class-path list separator: ; on Windows, : elsewhere.
no setter

Functions

defaultLibjvmPath({Map<String, String>? environment}) String
The path to libjvm for the current platform.
doubleFromBits(int bits) double
Reinterprets bits as a jdouble.
floatFromBits(int bits) double
Reinterprets the low 32 bits of bits as a jfloat.
jsig(String declaration) String
The JNI descriptor for a Java method declaration.
jtype(String typeName) String
The JNI descriptor for a Java type, as written in source.
libjvmUnder(String javaHome) String
The platform-specific location of libjvm under a JDK home.
searchLibjvm({Map<String, String>? environment}) LibjvmSearch
Searches for libjvm without throwing, reporting every candidate tried.

Exceptions / Errors

JavaException
A Java throwable that crossed into Dart.
JniError
Thrown when the JNI layer itself cannot proceed.
JniLookupError
Thrown when a class, method or field cannot be resolved.