Skip to content
Nuvyntra Labs

Platform integration

Java and Kotlin (desktop)

JNA wrapper: JVM jar plus the native library that matches the machine RID.

Overview

JNA wrapper over the C ABI. You need two zips: the JVM jar and the native library for your OS.

1. Download

From NuvexaDB v1.0.6, pick one pair that matches the machine that will run the JVM:

Your machineJVM zipNative zipLibrary file inside the native zip
macOS Apple SiliconNuvexaDB-Java-osx-arm64.zipNuvexaDB-Native-osx-arm64.ziplibnuvexa.dylib
Linux x64NuvexaDB-Java-linux-x64.zipNuvexaDB-Native-linux-x64.ziplibnuvexa.so
Windows x64NuvexaDB-Java-win-x64.zipNuvexaDB-Native-win-x64.zipnuvexa.dll

The JVM zip contains jvm-<version>.jar (and usually jvm-<version>-sources.jar). The implementation is the same on every RID; the native zip is what must match the CPU.

For Android, use android.md (NuvexaDB-Android.zip) instead of these desktop jars.

2. Empty project

mkdir acme-store && cd acme-store
gradle init --type java-application --dsl kotlin --package com.acme.store

Or a Kotlin JVM app with the same Gradle layout.

3. Add the downloaded package

Copy the jar next to the project (example libs/jvm-1.0.6.jar). In build.gradle.kts:

dependencies {
    implementation(files("libs/jvm-1.0.6.jar"))
    implementation("net.java.dev.jna:jna:5.17.0")
    implementation("org.json:json:20250107")
}

Point the process at the native file:

export NUVEXA_NATIVE_LIB="/absolute/path/to/libnuvexa.dylib"   # or .so / nuvexa.dll

4. Create, open, close

Kotlin:

import nuventra.nuvexadb.NuvexaDatabase

val path = "app.nvx"
NuvexaDatabase.create(path, key).use { db ->
    // work
}

if (NuvexaDatabase.isEncrypted(path) && key == null) {
    error("Encrypted .nvx — pass the key")
}

NuvexaDatabase.open(path, key).use { db ->
    // work; close() runs at the end of use
}

Java: NuvexaDatabase.create(path, key) and try-with-resources (AutoCloseable). Pass null for a plaintext file.

5. Delete the database

Close first, then delete the file (and app.nvx-wal if present):

db.close()
java.nio.file.Files.deleteIfExists(java.nio.file.Path.of(path))
java.nio.file.Files.deleteIfExists(java.nio.file.Path.of(path + "-wal"))

6. Collections

The first insert into a name creates that collection.

db.insert("users", """{"name":"Ada","age":36}""")
println(db.listCollections())
db.renameCollection("users", "people")
db.dropCollection("people")

7. Documents

val id = db.insert("users", """{"name":"Ada","age":36}""")
db.insertMany("users", """[{"name":"Grace","age":85},{"name":"Cara","age":21}]""")
val ada = db.findById("users", id)
db.replace("users", """{"_id":"$id","name":"Ada Lovelace","age":36}""")
val deleted = db.deleteById("users", id)
val rows = db.execute("""db.users.find({ age: { ${'$'}gte: 21 } }).sort({ name: 1 }).limit(20)""")

On 1.0.2+: db.execute("""db.users.update({ name: "Cara" }, { ${'$'}set: { age: 22 } })""") and db.execute("""db.users.delete({ age: { ${'$'}lt: 18 } })""").

8. Password for an encrypted file

Pass the same key string to create and open. Prefer a long random secret stored in the OS keychain or a secrets manager. Do not hard-code 1234 in the repo.

db.changeEncryptionKey(currentKey, nextKey)

See Encryption notes.

Discussion

Comment on NuvexaDB. The thread lives on this component's GitHub repository (nuvyntralabs/NuvexaDB). Sign in with GitHub — Giscus uses Discussions, Utterances uses Issues.