← Back to sschr15 home


Kotlin/Native and JNI

Are you interested in Kotlin, the official language of Android and a fantastic replacement for Java? What about JNI, that thing that OpenJDK is now attempting to restrict for safety reasons in upcoming JDK versions?

Kotlin already has Multiplatform, why would you want to use JNI?

Thank you for the question, undisclosed ephemeral person I created to ask this question. My answer, as with the various other projects I have undergone (see my other blog posts), is...

"no reason"

Setup

I created a proof-of-concept project as a way to mess around with Kotlin and see what happens. The project is a Kotlin/Multiplatform project with a JVM target (the Java side, with .java files that actually have the native methods) and a native target (for the real implementations).

Ten JNI functions are in the proof-of-concept:

The Java Side

For the PoC, I created a rather simple class: NativeBackedIntArray. This essentially reimplements int[] but uses a native array to store the data. The class implements AutoCloseable to allow for automatic cleanup of the native memory when the object is done being used. The native methods have parameters and return types meant for referencing memory addresses, and user-facing methods are provided as normal object methods to hide the implementation details.

The Native Side

The native side is written with Kotlin/Native and implements the native methods defined in the Java side. Thanks to the help of people with more low-level experience, many methods are implemented in ways that manage to outpace the Java implementation in terms of performance. Through heavy use of the @CName annotation, the actual function names can be sensical while still conforming to how JNI functions are meant to be named.

Speed compared to the Java implementation varies, with some methods (those involving direct memory access) being significantly faster than the Java implementation, while others (those involving individual element access) take a big hit in performance:

Results

Writing JNI methods in Kotlin/Native for no reason but to use Kotlin/Native is in general a bad idea, but using Kotlin/Native as the bridge between a Java API face and some other native library does have some merit. Just maybe don't use native code in all the places where a pure Java or Kotlin/JVM implementation works, and also maybe keep the overall overhead of Kotlin/Native and JNI in general in mind when writing JNI methods.

This project is available on GitHub, but as with most of my projects, it may be messy and definitely isn't documented. Good luck in any future Kotlin endeavors!