KubeMQ is a message queue and message broker designed for containerized workloads. The KubeMQ Java SDK provides a type-safe client for all KubeMQ messaging patterns — Events, Events Store, Commands, Queries, and Queues — over gRPC transport with built-in TLS, authentication, and reconnection support.
Migrating from v1? See MIGRATION.md for the upgrade guide.
- Java 11 or higher (LTS releases 11, 17, and 21 are tested in CI)
- KubeMQ server running (default:
localhost:50000) — install guide - Maven 3.6+ or Gradle 7+
<dependency>
<groupId>io.kubemq.sdk</groupId>
<artifactId>kubemq-sdk-Java</artifactId>
<version>2.1.1</version>
</dependency>implementation 'io.kubemq.sdk:kubemq-sdk-Java:2.1.1'The simplest way to send and receive a message:
// Publish an event (fire-and-forget)
PubSubClient client = PubSubClient.builder()
.address("localhost:50000")
.clientId("quick-start")
.build();
client.sendEventsMessage(EventMessage.builder()
.channel("hello")
.body("Hello KubeMQ!".getBytes())
.build());
client.close();See Messaging Patterns below for per-pattern quick starts including subscribing.
| Pattern | Delivery Guarantee | Use When | Example Use Case |
|---|---|---|---|
| Events | At-most-once | Fire-and-forget broadcasting to multiple subscribers | Real-time notifications, log streaming |
| Events Store | At-least-once (persistent) | Subscribers must not miss messages, even if offline | Audit trails, event sourcing, replay |
| Queues | At-least-once (with ack) | Work must be processed by exactly one consumer with acknowledgment | Job processing, task distribution |
| Commands | At-most-once (request/reply) | You need confirmation that an action was executed | Device control, configuration changes |
| Queries | At-most-once (request/reply) | You need to retrieve data from a responder | Data lookups, service-to-service reads |
Publish an event:
PubSubClient client = PubSubClient.builder()
.address("localhost:50000")
.clientId("events-sender")
.build();
EventSendResult result = client.sendEventsMessage(EventMessage.builder()
.channel("notifications")
.body("Hello KubeMQ!".getBytes())
.build());
System.out.println("Event sent: " + result.getId());
client.close();Subscribe to events:
PubSubClient client = PubSubClient.builder()
.address("localhost:50000")
.clientId("events-receiver")
.build();
client.subscribeToEvents(EventsSubscription.builder()
.channel("notifications")
.onReceiveEventCallback(event ->
System.out.println("Received: " + new String(event.getBody())))
.onErrorCallback(err -> System.err.println("Error: " + err.getMessage()))
.build());
Thread.sleep(30000);
client.close();Expected output (subscriber):
Received: Hello KubeMQ!
Send a queue message:
QueuesClient client = QueuesClient.builder()
.address("localhost:50000")
.clientId("queue-sender")
.build();
QueueSendResult result = client.sendQueuesMessage(QueueMessage.builder()
.channel("tasks")
.body("Process this job".getBytes())
.build());
System.out.println("Sent, expired: " + result.isExpired());
client.close();Receive and acknowledge:
QueuesClient client = QueuesClient.builder()
.address("localhost:50000")
.clientId("queue-receiver")
.build();
QueuesPollResponse response = client.receiveQueuesMessages(QueuesPollRequest.builder()
.channel("tasks")
.pollMaxMessages(1)
.pollWaitTimeoutInSeconds(10)
.build());
for (QueueMessageReceived msg : response.getMessages()) {
System.out.println("Processing: " + new String(msg.getBody()));
msg.ack();
}
client.close();Expected output (receiver):
Processing: Process this job
Handle a command (responder):
CQClient client = CQClient.builder()
.address("localhost:50000")
.clientId("command-handler")
.build();
client.subscribeToCommands(CommandsSubscription.builder()
.channel("device.control")
.onReceiveCommandCallback(cmd -> {
System.out.println("Executing: " + new String(cmd.getBody()));
return CommandResponseMessage.builder()
.requestId(cmd.getId())
.isExecuted(true)
.build();
})
.onErrorCallback(err -> System.err.println("Error: " + err.getMessage()))
.build());Send a command (caller):
CQClient client = CQClient.builder()
.address("localhost:50000")
.clientId("command-sender")
.build();
CommandResponseMessage response = client.sendCommandRequest(CommandMessage.builder()
.channel("device.control")
.body("restart".getBytes())
.timeout(5000)
.build());
System.out.println("Executed: " + response.isExecuted());
client.close();Expected output (sender):
Executed: true
For more examples, see the examples directory.
| Parameter | Type | Default | Description |
|---|---|---|---|
address |
String |
localhost:50000 |
KubeMQ server gRPC address (host:port). Falls back to KUBEMQ_ADDRESS env var. |
clientId |
String |
Auto-generated UUID | Unique identifier for this client instance |
authToken |
String |
null |
JWT authentication token for server access |
tls |
boolean |
false |
Enable TLS encryption for the connection |
tlsCertFile |
String |
null |
Path to TLS certificate file (PEM format) |
tlsKeyFile |
String |
null |
Path to TLS private key file (PEM format) |
tlsCaCertFile |
String |
null |
Path to CA certificate for server verification |
maxReceiveSize |
int |
104857600 |
Maximum inbound message size in bytes (100MB) |
reconnectIntervalSeconds |
int |
5 |
Seconds between reconnection attempts |
logLevel |
Level |
INFO |
Logging level (TRACE, DEBUG, INFO, WARN, ERROR, OFF) |
Example:
PubSubClient client = PubSubClient.builder()
.address("kubemq-server:50000")
.clientId("my-service")
.authToken("eyJ...")
.tls(true)
.tlsCertFile("/certs/client.pem")
.tlsKeyFile("/certs/client-key.pem")
.tlsCaCertFile("/certs/ca.pem")
.reconnectIntervalSeconds(10)
.build();The SDK uses a typed exception hierarchy rooted at KubeMQException:
| Exception | Category | When |
|---|---|---|
ConnectionException |
Retryable | Server unavailable, network failure |
KubeMQTimeoutException |
Retryable | Deadline exceeded, server too slow |
AuthenticationException |
Non-retryable | Invalid or expired auth token |
AuthorizationException |
Non-retryable | Insufficient permissions |
ValidationException |
Non-retryable | Invalid request parameters |
GRPCException |
Varies | gRPC transport errors |
try {
client.sendEventsMessage(message);
} catch (ConnectionException e) {
log.warn("Connection failed (retryable): {}", e.getMessage());
} catch (AuthenticationException e) {
log.error("Auth failed (fix credentials): {}", e.getMessage());
} catch (ValidationException e) {
log.error("Invalid request: {}", e.getMessage());
} catch (KubeMQException e) {
log.error("SDK error: {}", e.getMessage());
}| Problem | Likely Cause | Quick Fix |
|---|---|---|
UNAVAILABLE: io exception |
Server not running or wrong address | Verify server is running and address is correct |
UNAUTHENTICATED: invalid token |
Missing or expired auth token | Check .authToken() value and expiry |
| Subscriber not receiving messages | Wrong channel name or subscriber started after publisher | Verify channel names match; for Events, subscriber must be running first |
RESOURCE_EXHAUSTED: message too large |
Message body exceeds 100MB default | Increase maxReceiveSize or split payload |
SSLHandshakeException |
TLS misconfiguration | Verify cert paths and expiry; ensure server TLS mode matches client |
For detailed solutions with code examples, see TROUBLESHOOTING.md.
| Characteristic | Value | Notes |
|---|---|---|
| Max message size | 100 MB | Configurable via maxReceiveSize |
| Connection model | Single gRPC channel | All operations multiplex over one HTTP/2 connection |
| Serialization | Protocol Buffers | Binary encoding for efficient wire format |
| Batch send | Supported | sendQueuesMessages(List<QueueMessage>) |
| Batch receive | Supported | pollMaxMessages in QueuesPollRequest |
Tips:
- Reuse client instances — one client per pattern handles all operations efficiently
- Use batch APIs for high-throughput queue workloads
- Do not block subscription callbacks — offload heavy work to a separate executor
- Close clients when done — all client classes implement
AutoCloseable
See BENCHMARKS.md for JMH benchmark results.
| Java Version | Status |
|---|---|
| Java 11 (LTS) | Supported (minimum, compile target) |
| Java 17 (LTS) | Supported (tested in CI) |
| Java 21 (LTS) | Supported (tested in CI) |
See COMPATIBILITY.md for the full SDK-to-server version matrix.
We welcome contributions! Please see CONTRIBUTING.md for guidelines on:
- Development setup and building
- Commit message format
- Pull request process
- Deprecation policy
This project is licensed under the MIT License — see the LICENSE file for details.
- CHANGELOG.md — Release history
- MIGRATION.md — v1 to v2 migration guide
- TROUBLESHOOTING.md — Common issues and solutions
- Examples — Runnable code examples for all patterns
- KubeMQ Documentation — Server documentation and guides