Repository navigation
UnsatisfiedLinkError: no objectbox-jni-windows-x64 when installed to Program Files #1225
Copy link
Copy link
Open
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or request
Description
Is there an existing issue?
- I have searched existing issues
Build info
- ObjectBox version: 5.0.0
- OS: Windows 10
- Device/ABI/architecture: x64
Steps to reproduce
I am building a KMP project with ObjectBox. When I run the jvmApp module directly (e.g., from the IDE), the ObjectBox .dll file is found and loaded correctly.
However, when I build a distributable package for deployment (e.g., using jpackage), the .dll file seems to be missing from the final package, causing it to fail at runtime.
What could be the problem?
(I apologize for asking this again. I posted this on StackOverflow, but since I haven't received a response yet, I'm posting it here as well.)
Expected behavior
Create objectbox-jni-windows-x64, when the installer installs the executable.
Actual behavior
The .dll file is not included when the installer installs the executable.
Code
Code
settings.gradle.kts(root)
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == "io.objectbox") {
useModule("io.objectbox:objectbox-gradle-plugin:${requested.version}")
}
if (requested.id.id == "com.google.dagger") {
useModule("com.google.dagger:dagger:${requested.version}")
}
if (requested.id.id == "com.google.dagger:hilt-android") {
useModule("com.google.dagger:hilt-android:${requested.version}")
}
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "FireAlarmKMP"
include(":androidApp")
include(":jvmApp")
include(":shared:data-common")
include(":shared:data-jvm")
include(":shared:domain")
include(":shared:presentation-common")
include(":shared:data-android")
include(":shared:core-common")
include(":shared:core-android")
include(":shared:core-jvm")
include(":shared:presentation-android")
include(":shared:presentation-jvm")
build.gradle.kts(:jvmApp)
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.jetbrains.kotlin.jvm)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.kapt)
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}
dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing)
implementation(libs.dagger)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.lifecycle.runtime.compose)
configurations["kapt"].dependencies.add(project.dependencies.create(libs.dagger.compiler.get()))
implementation(project(":shared:presentation-common"))
implementation(project(":shared:presentation-jvm"))
implementation(project(":shared:domain"))
implementation(project(":shared:data-common"))
implementation(project(":shared:data-jvm"))
implementation(project(":shared:core-common"))
implementation(project(":shared:core-jvm"))
}
compose.desktop {
application {
mainClass = "com.blabla.jvmapp.MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb, TargetFormat.Exe)
packageName = "jvmapp"
packageVersion = "1.0.28"
}
}
}
build.gradle.kts(:data-jvm)
plugins {
alias(libs.plugins.jetbrains.kotlin.jvm)
alias(libs.plugins.kapt)
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}
dependencies {
implementation(libs.arrow.core)
implementation(libs.arrow.fx.coroutines)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.objectbox.windows)
implementation(libs.objectbox.kotlin)
kapt(libs.objectbox.processor)
implementation(libs.dagger)
kapt(libs.dagger.compiler)
implementation(project(":shared:data-common"))
implementation(project(":shared:core-common"))
implementation(project(":shared:domain"))
}
apply(plugin = "java-library")
apply(plugin = "io.objectbox")
Logs, stack traces
Logs
Caused by: java.lang.UnsatisfiedLinkError: no objectbox-jni-windows-x64 in java.library.path: C:\Program Files\com.blabla.jvmapp\app/resources
at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.base/java.lang.Runtime.loadLibrary0(Unknown Source)
at java.base/java.lang.System.loadLibrary(Unknown Source)
at io.objectbox.internal.NativeLibraryLoader.<clinit>(NativeLibraryLoader.java:98)
... 48 more
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or request
Activity
greenrobot-team commentedon Dec 1, 2025
By default the library file is extracted into the working directory from the JAR resources when ObjectBox code is first run. See NativeLibraryLoader. It looks like that default behavior doesn't work for a Kotlin Multiplatform app?
Assuming that extracting doesn't work, the solution is likely to manually include the library and make sure it's placed in the correct location before the app uses ObjectBox APIs. You can find the library included in the platform-specific JAR, so for Windows in the Maven artifact
io.objectbox:objectbox-windows.udyr-woo commentedon Dec 1, 2025
I've found the root cause. When installed in Program Files, the app lacks the permissions to extract the DLL file at runtime. If installed in a directory other than Program Files, the DLL is generated successfully, and the app starts normally.
[-]I couldn't create objectbox-jni-windows-x64[/-][+]UnsatisfiedLinkError: no objectbox-jni-windows-x64 when installed to Program Files[/+]greenrobot-team commentedon Dec 8, 2025
Thanks for the update!
The proper solution to install to (the write protected) Program Files on Windows would be to install the DLL into the application installation directory. I'm not sure how to do this when using Kotlin Multiplatform build tools, but maybe we should at least provide general documentation on how to extract and bundle the required ObjectBox database library file(s) for desktop applications.
udyr-woo commentedon Dec 9, 2025
I tried modifying build.gradle to include the DLL during the installation phase as you suggested, but unfortunately, it didn't work. If preparing the official documentation is going to take some time, could you please provide a temporary solution or instructions right here?
greenrobot-team commentedon Dec 9, 2025
I already told you that the DLL can be extracted from the Maven JAR artifact (and it also is automatically extracted if running the app during testing). Bundling that file in the installation archive or executable is specific to the build system and setup.
jacobian2020 commentedon Apr 12, 2026
I am running into the same issue with Windows and macOS. Even if we bundled and extracted on our own, this line would still throw the error.
Is there a way to override this?
Or at the very least allow the developer to configure where to look and extract that file. Like skiko does it here.
@greenrobot-team As it stands, right now objectbox is unusable for KMP apps on macOS and windows.
greenrobot-team commentedon Apr 13, 2026
Could you share an example project for us to reproduce this? Maybe this is also related to a newer JDK or the OS disallowing System.load?
I guess I'll convert this issue into a feature request then! For anyone else interested, please thumbs up the first comment!
Edit: for our reference, this is internal issue
objectbox-java#301hiSandog commentedon Jul 1, 2026
The
Program Filesinstall path may be exposing either a space-in-path issue or a native library extraction/permission issue. It would help to include the exact app install path, the directory where ObjectBox tries to extract/loadobjectbox-jni-windows-x64, and whether running the same app from a user-writable path works. That should make it clear whether the fix belongs in path quoting or native library extraction fallback logic.greenrobot-team commentedon Jul 6, 2026
The API library expects to find the database library for the current platform in the working directory. The code is open, check it yourself: NativeLibraryLoader
Also, apps typically don't have write access when being installed in Windows Program Files. Hence, the recommendation above to pre-package the extracted database library file and install it at the expected location.
Anyhow, are you saying you have found an issue in the
NativeLibraryLoadercode? Then please feel free to create a new GitHub issue and share details.