Composing a JNI Library from Pre-built Binaries
You can open this sample inside an IDE using the IntelliJ native importer or Eclipse Buildship. |
This sample shows how to compose a Java Native Interface (JNI) library from pre-built binaries. It may happen that we don’t have source code access and all we have are pre-built binaries of the native component. This sample will show how to use the pre-built binaries with the JNI Library Plugin to compose a JNI library.
The pre-built binaries offered with this sample may not be compatible on your system which could lead to runtime failures. |
In this sample, the JNI library’s implementation languages are Java; however, this applies to other JVM as well.
The plugin sources the native libraries for the JNI JAR from the native runtime file collection. The sample configures the file collection to include the pre-built shared library for each variant:
plugins {
id 'java'
id 'dev.nokee.jni-library'
}
import dev.nokee.runtime.nativebase.OperatingSystemFamily
String getLibraryFilePathFor(OperatingSystemFamily osFamily) {
if (osFamily.windows) {
return "pre-built-libraries/windows/jni-greeter.dll"
} else if (osFamily.linux) {
return "pre-built-libraries/linux/libjni-greeter.so"
} else if (osFamily.macOS) {
return "pre-built-libraries/macos/libjni-greeter.dylib"
}
throw new GradleException("Unknown operating system family '${osFamily}'.")
}
library {
targetMachines = [machines.windows.x86_64, machines.linux.x86_64, machines.macOS.x86_64]
variants.configureEach {
def prebuiltLibraryFile = file(getLibraryFilePathFor(targetMachine.operatingSystemFamily))
nativeRuntimeFiles.setFrom(prebuiltLibraryFile)
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.12'
}
plugins {
id("java")
id("dev.nokee.jni-library")
}
import java.util.concurrent.Callable
import dev.nokee.runtime.nativebase.OperatingSystemFamily
fun getLibraryFilePathFor(osFamily: OperatingSystemFamily): String {
if (osFamily.isWindows) {
return "pre-built-libraries/windows/jni-greeter.dll"
} else if (osFamily.isLinux) {
return "pre-built-libraries/linux/libjni-greeter.so"
} else if (osFamily.isMacOs) {
return "pre-built-libraries/macos/libjni-greeter.dylib"
}
throw GradleException("Unknown operating system family '${osFamily}'.")
}
library {
targetMachines.set(listOf(machines.windows.x86_64, machines.linux.x86_64, machines.macOS.x86_64))
variants.configureEach {
val prebuiltLibraryFile = file(getLibraryFilePathFor(targetMachine.operatingSystemFamily))
nativeRuntimeFiles.setFrom(prebuiltLibraryFile)
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("junit:junit:4.12")
}
The plugin adds the pre-built binaries to the java.library.path
during testing automatically:
$ ./gradlew test BUILD SUCCESSFUL 3 actionable tasks: 3 executed
The plugin also adds the pre-built binaries to the JNI JAR just as it would when building a JNI shared library from the source:
$ ./gradlew assemble BUILD SUCCESSFUL 3 actionable tasks: 2 executed, 1 up-to-date $ jar xvf ./build/libs/jni-library-composing-from-pre-built-binaries-macos.jar created: META-INF/ inflated: META-INF/MANIFEST.MF created: macos/ inflated: macos/libjni-greeter.dylib
For more information, see JNI Library Plugin and Building JNI Projects chapters.