# Use the Java SDK

**Applies to:** current development source bundles. Obtain a matched client/server release through [early-access support](mailto:info@simplemagic.com); registry publication is not available yet. Paths below are relative to the supplied source checkout.

Blocking Java 21+ client using the shared C transport through JNI. Works from
Java and other JVM languages. Initial source release; not published to Maven Central.

## Build

Install the [C SDK dependencies](c-client.html), then:

```sh
make -C java-smkv JAVA_HOME=/path/to/jdk-21
```

This produces `build/smkv-client.jar`, `libsmkv_jni`, and `libsmkv`.
Use the jar on the classpath and keep both native libraries in the same directory.
Pass `-Djava.library.path=/absolute/path/to/java-smkv/build` when starting Java.
OpenSSL and json-c must also be installed. Build native libraries for the target
OS/architecture; Windows has not been qualified. `pom.xml` builds only the Java jar.

## Usage

```java
import com.simplemagic.smkv.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

try (var client = new Client("127.0.0.1:7379")) {
    byte[] key = "42".getBytes(StandardCharsets.UTF_8);
    client.put(key, new byte[]{0, 1}, new WriteOptions(60000L, true, false, false));
    byte[] value = client.get(key);
    var users = client.table("users");
    users.put(key, Map.of("name", "Ada", "visits", 1L), WriteOptions.DEFAULT);
    System.out.println(users.get(key));
}
```

Keys/raw values are byte arrays. Columns accept byte[], String, Boolean, signed
integral wrappers, and Double. Reads preserve int64 as Long and float64 as Double.
Table get supports projection and explicit replica reads; update accepts columns
to set and a list to remove, atomically. `WriteOptions` exposes TTL and acknowledgment
flags. Null TTL means no expiry on put and preserves expiry on update; zero expires
immediately. Delete rejects a non-null TTL.

## Cluster and security

`Client.cluster(List.of("host:7381"))` accepts **management** seeds. `get(key, true)`
explicitly allows stale replica reads. Discovery occurs on the first request.

For advanced configuration, pass `Map<String,Object>` using the
[C configuration schema](c-client.html#configuration-routing-and-security).
Data `security` and `management_security` are separate maps; `ca` is a PEM path,
`name`/`token` provide bearer authentication. Omit either feature when not needed.
TLS always verifies CA and hostname/IP; there is no insecure mode or fallback.

## Lifecycle, errors, and release scope

Use try-with-resources. Client methods are thread-safe; a client serializes requests
on one connection. Use a bounded number of clients for concurrency. `close()`
interrupts active I/O, waits for callers to exit, and releases native resources.
There is no finalizer; explicitly close every client.

`SmkvException.code()` returns the server/client code and `outcomeUnknown()` indicates
that a mutation may have completed. Only explicit WrongOwner is automatically retried.
The default deadline is five seconds including lock wait and discovery; native DNS
may exceed it. Configure `timeout_ms` to change it. Default limits: 1 KiB keys and
1 MiB values, adjustable to match the server. Native/library-loading errors remain
normal JVM exceptions.

No async API, scans, batch operations, Windows support, or load qualification yet.
See [native transport limits](c-client.html#lifecycle-and-limits) and
[qualification](sdk-clients.html#initial-release-limits).

Build/run `examples/Basic.java` with the generated jar on the classpath and the
native directory in `java.library.path`. `make test-client` builds the qualification
entry point; it does not publish the jar or start any server.

## Logical databases

Select the database when constructing the client (or cluster client):

```java
new Client(Map.of("endpoint", "127.0.0.1:7379", "database", "orders"))
```

Omitting the option uses `default` and preserves existing wire keys. Named
databases require database-aware development servers (cluster protocol 5, or 6
with experimental group sync). Names use 1–64 ASCII letters, digits, `_` or `-`.
The selection scopes raw keys and all table operations, including replica reads.
The complete database-prefixed key is hashed for routing and counts against the
key-size limit. Databases share cluster capacity and durability settings.

Use the matching database-aware native library and, for Java, JNI bridge. These
bindings require the ABI 2 constructor `smkv_create_v2`; an older library fails to
load or construct a client rather than silently selecting the default database.
