Apache Iggy
SDKJava

Examples

Runnable Java examples from the core repository, built with Gradle, and how to start a server for them.

Runnable examples live in the examples/java directory of the core repository as a standalone Gradle project. The project builds against the in-repo SDK (via an includeBuild substitution), so the examples always match the SDK source in the same checkout. Java 17 is recommended. The included gradlew wrapper downloads the pinned Gradle version on first run.

Starting the server

The Java SDK speaks the VSR (Viewstamped Replication) wire protocol, so the examples run against the VSR server. The examples log in as iggy/iggy, and root credentials are applied only on the very first startup, when no data directory exists yet. Start the server with the default root credentials:

cargo run --bin iggy-server -- --fresh --with-default-root-credentials

Alternatively, set IGGY_ROOT_USERNAME=iggy and IGGY_ROOT_PASSWORD=iggy before the first start. If an example fails with InvalidCredentials, the server data directory (local_data by default) was created with different credentials: delete it and start the server again with the defaults. This setup is intended only for development and testing.

Running the examples

Run each example from the examples/java directory with its Gradle task:

  • gettingstarted - basic blocking producer and consumer, the best starting point.

    ./gradlew runGettingStartedProducer
    ./gradlew runGettingStartedConsumer
  • messageheaders - message metadata via custom header keys and values, with header-based routing instead of payload-based typing.

    ./gradlew runMessageHeadersProducer
    ./gradlew runMessageHeadersConsumer
  • messageenvelope - JSON envelope pattern for polymorphic message handling (order events wrapped in envelopes for type identification).

    ./gradlew runMessageEnvelopeProducer
    ./gradlew runMessageEnvelopeConsumer
  • multitenant - multi-tenant isolation: per-tenant streams, users with stream-specific permissions, and concurrent producers and consumers across tenants.

    ./gradlew runMultiTenantProducer
    ./gradlew runMultiTenantConsumer
  • sinkdataproducer - high-volume data generation (1000+ messages per batch) with realistic records, for testing and benchmarking.

    ./gradlew runSinkDataProducer
  • streambuilder - a combined producer and consumer in a single class.

    ./gradlew runStreamBasic
  • async - the async client: CompletableFuture chaining, submitting multiple sends without blocking, backpressure, error recovery with exponential backoff, and thread pool separation.

    ./gradlew runAsyncProducer
    ./gradlew runAsyncConsumer
  • tcptls - TLS-encrypted TCP connections with CA certificate verification. Requires a TLS-enabled server:

    IGGY_TCP_TLS_ENABLED=true \
    IGGY_TCP_TLS_CERT_FILE=core/certs/iggy_cert.pem \
    IGGY_TCP_TLS_KEY_FILE=core/certs/iggy_key.pem \
    cargo run --bin iggy-server
    ./gradlew runTcpTlsProducer
    ./gradlew runTcpTlsConsumer

Blocking vs. async

Use the blocking client for scripts, CLI tools, integration tests, and anywhere sequential code is easier to reason about. Use the async client for high throughput, reactive applications, and composing non-blocking requests with CompletableFuture. The async client runs I/O on Netty event loop threads: never block them with .join(), .get(), Thread.sleep(), or blocking I/O inside thenApply/thenAccept. Offload blocking work with thenApplyAsync(fn, executor). The examples/java README covers these async patterns in detail.

On this page