Skip to content

Latest commit

 

History

History

README.md

SLIM Java Bindings

Java bindings for SLIM generated via uniffi-bindgen-java.

Features

  • Native Java Interface: Idiomatic Java API with sync methods; async variants via CompletableFuture available
  • Java 21: Built for modern Java with records and latest language features
  • JNA Integration: Seamless native library loading via Java Native Access (JNA)
  • Complete Examples: Server, Point-to-Point, and Group messaging examples
  • slimrpc Support: Protocol Buffers RPC over SLIM - see SLIMRPC.md for details
  • Task Automation: Integrated with Taskfile for easy builds and testing

Requirements

  • Java 21 or higher
  • Maven 3.8+
  • Rust toolchain (for building native library)
  • uniffi-bindgen-java (auto-installed via Taskfile)

Quick Start

1. Generate Bindings

cd java
task generate

This will:

  • Build the Rust bindings library
  • Install uniffi-bindgen-java (if not present)
  • Generate Java source files
  • Copy native libraries to the correct platform directory

2. Build Java Bindings

task build

Creates a JAR at target/slim-bindings-java-1.2.0.jar.

3. Install to Local Maven Repository

task install

Makes the bindings available to the examples and other local projects.

4. Run Examples

# Start server
task examples:server

# Point-to-point (in separate terminals)
task examples:p2p:alice
task examples:p2p:bob

# Group messaging (in separate terminals)
task examples:group:moderator
task examples:group:client-1
task examples:group:client-2

Architecture

┌─────────────────────────┐
│  Java Application       │
│  (Your Code)            │
└───────────┬─────────────┘
            │
            │ Sync / CompletableFuture API
            ▼
┌─────────────────────────┐
│  Generated Java Classes │
│  (uniffi-bindgen-java)  │
└───────────┬─────────────┘
            │
            │ JNA
            ▼
┌─────────────────────────┐
│  Native Library         │
│  libslim_bindings.so    │
│  (Rust + UniFFI)        │
└─────────────────────────┘

Directory Structure

java/
├── Taskfile.yaml           # Build automation
├── pom.xml                 # Maven configuration
├── uniffi.toml             # UniFFI Java bindings config
├── README.md               # This file
├── generated/              # Generated code (gitignored)
│   ├── uniffi/slim_bindings/  # Java source files
│   └── native/             # Native libraries by platform (JNA format)
│       ├── darwin-x86-64/
│       ├── darwin-aarch64/
│       ├── linux-x86-64/
│       ├── linux-aarch64/
│       ├── win32-x86-64/
│       └── win32-aarch64/
└── examples/               # Java examples
    ├── Taskfile.yaml
    ├── pom.xml
    └── src/main/java/io/agntcy/slim/examples/
        ├── common/         # Shared utilities
        ├── Server.java     # Server example
        ├── PointToPoint.java  # P2P messaging
        └── Group.java      # Group messaging

API Overview

Initialization

import io.agntcy.slim.bindings.*;

// Initialize with defaults
SlimBindings.initializeWithDefaults();

// Or with OpenTelemetry tracing
SlimBindings.initializeWithTracing("my-app", "localhost:4317");

Creating an App

Service service = SlimBindings.getGlobalService();
Name appName = new Name("org", "namespace", "app");

// Create app with shared secret
App app = service.createAppWithSecret(appName, "my-secret-min-32-chars!!!!!!!!!!");

Connecting to Server

// Create client config
ClientConfig config = SlimBindings.newInsecureClientConfig("http://localhost:46357");

// Connect (sync)
Long connectionId = service.connect(config);

Transport Authentication (gRPC connection)

Separate from the app identity passed to createAppWithSecret and friends, the gRPC connection to a SLIM node can carry its own credentials via ClientConfig.setAuth (and ServerConfig.setAuth when hosting). Supported modes are Basic, StaticJwt, Jwt, Spire, and Oidc.

OIDC, client side (client-credentials flow):

ClientConfig config = SlimBindings.newInsecureClientConfig("http://localhost:46357");
config.setAuth(new ClientAuthenticationConfig.Oidc(new OidcConfig(
    "https://auth.example.com",  // issuerUrl
    "my-client",                 // clientId
    "s3cr3t",                    // clientSecret
    null,                        // audience
    null, null, null,            // refreshToken, refreshTokenFile, accessTokenFile
    "openid profile",            // scope
    Duration.ofSeconds(30),      // timeout        (client-side)
    null,                        // jwksTtl        (server-side)
    null,                        // claimCacheTtl  (server-side)
    null)));                     // policy         (server-side)

Long connectionId = service.connect(config);

For the refresh-token flow set refreshToken — or refreshTokenFile, which is rewritten in place as tokens rotate — instead of clientSecret.

Server side, verifying incoming JWTs against the issuer's JWKS endpoint, optionally restricting access by claim:

ServerConfig config = SlimBindings.newInsecureServerConfig("127.0.0.1:46357");
config.setAuth(new ServerAuthenticationConfig.Oidc(new OidcConfig(
    "https://auth.example.com",
    null, null,
    "slim",                      // audience - required for verification
    null, null, null, null, null,
    Duration.ofHours(1),         // jwksTtl
    Duration.ofMinutes(1),       // claimCacheTtl
    new OidcPolicyConfig.Cel("\"admin\" in claims.groups"))));

policy accepts OidcPolicyConfig.Cel, OidcPolicyConfig.Rego (which must define package slim.auth with default allow = false), or OidcPolicyConfig.RegoFile. Client-only fields (scope, timeout) and server-only fields (jwksTtl, claimCacheTtl, policy) are ignored by the other side.

From a config file — SlimBindings.newConfigFromJson accepts a full gRPC client config, covering TLS material, backoff, and every authentication mode. The examples read the same document from SLIM_CLIENT_CONFIG:

{
  "endpoint": "http://127.0.0.1:46357",
  "tls": { "insecure": true },
  "auth": {
    "type": "oidc",
    "issuer_url": "https://auth.example.com",
    "client_id": "my-client",
    "client_secret": "s3cr3t",
    "audience": "slim",
    "policy": { "cel": "\"admin\" in claims.groups" }
  }
}

The schema matches data-plane/core/config/src/grpc/schema/client-config.schema.json in the slim repo.

Creating Sessions

Name remoteName = new Name("org", "namespace", "remote");

// Create point-to-point session
SessionConfig sessionConfig = new SessionConfig(
    SessionType.POINT_TO_POINT,
    null,  // maxRetries
    null,  // interval
    Map.of(),  // metadata
    new MlsSettings(100) // mlsSettings (null to disable)
);

Session session = app.createSessionAndWait(sessionConfig, remoteName);

Sending Messages

byte[] message = "Hello, SLIM!".getBytes();

// Publish and wait
session.publishAndWait(message, null, null);

Receiving Messages

Duration timeout = Duration.ofSeconds(30);
ReceivedMessage msg = session.getMessage(timeout);

System.out.println("Received: " + new String(msg.payload()));

Async Methods (CompletableFuture)

Async variants (*Async) returning CompletableFuture are available for all operations. They can be a good choice when using Virtual Threads (Java 21+), where blocking is cheap and you can use .get() or .join() without tying up OS threads.

When using the standard Java thread model (OS threads) with async methods, consider increasing the common pool parallelism:

java -Djava.util.concurrent.ForkJoinPool.common.parallelism=16 -jar myapp.jar

Available Tasks

Run task in the java/ directory to see all available tasks:

task                      # List all tasks
task generate             # Generate Java bindings
task build                # Build Java code and create JAR
task install              # Install JAR to local Maven repository
task clean                # Clean build artifacts and generated code
task examples:server      # Run server example
task examples:p2p:alice   # Run P2P receiver
task examples:p2p:bob     # Run P2P sender
task examples:group:*     # Run group examples

Examples

See examples/README.md for detailed example documentation.

Platform Support

Platform Architecture Status
macOS x86_64 ✅ Supported
macOS aarch64 (M1/M2) ✅ Supported
Linux x86_64 ✅ Supported
Linux aarch64 ✅ Supported
Windows x86_64 ✅ Supported

Resources

License

Copyright AGNTCY Contributors (https://github.com/agntcy)

SPDX-License-Identifier: Apache-2.0