Close a KubeMQ Java Client
Properly close a KubeMQ Java SDK client connection to release server resources and avoid leaks on shutdown.
Overview
Closing a client isn't an afterthought — it tells the broker and your own process that this connection is done, so both sides release what they were holding for it. A KubeMQ client is more than a socket: it's a gRPC channel plus whatever subscriptions and in-flight sends it's servicing. Skip the close and those linger — subscriptions keep streaming, the channel stays open — and in long-running services (or test suites spinning up many clients) you leak connections until the process dies.
Every KubeMQ client class implements AutoCloseable, so try-with-resources is the idiomatic way to guarantee close() runs when the block exits, even on exception. Calling close() explicitly drains in-flight operations and releases the gRPC channel and any background threads.
Gotchas: the drain window is bounded, not unlimited, so a slow consumer can still lose the tail of a burst if you close mid-stream; a closed client is dead forever — no reconnect on the same instance, build a new one; and when a process owns several client types (PubSubClient, QueuesClient, CQClient), close them in reverse construction order so nothing gets routed to a channel that's already tearing down.
Prerequisites
- KubeMQ server running on
localhost:50000 - Java SDK installed (
implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1'(Gradle) or Maven dependency from Getting Started)
Code
package io.kubemq.example.connection;
import io.kubemq.sdk.common.ServerInfo;
import io.kubemq.sdk.pubsub.PubSubClient;
import io.kubemq.sdk.queues.QueuesClient;
import io.kubemq.sdk.cq.CQClient;
/**
* Close Example
*
* Demonstrates proper client lifecycle management: creating, using,
* and closing KubeMQ clients. Shows try-with-resources and explicit close patterns.
*/
public class CloseExample {
private static final String ADDRESS = "localhost:50000";
private static final String CLIENT_ID = "java-connection-close-client";
public void tryWithResourcesExample() {
System.out.println("=== Try-With-Resources Pattern ===\n");
// Client auto-closes when leaving try block
try (QueuesClient client = QueuesClient.builder()
.address(ADDRESS)
.clientId(CLIENT_ID + "-twr")
.build()) {
ServerInfo info = client.ping();
System.out.println("Connected: " + info.getHost());
System.out.println("Client will be auto-closed when leaving this block.\n");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
System.out.println("Client has been automatically closed.\n");
}
public void explicitCloseExample() {
System.out.println("=== Explicit Close Pattern ===\n");
// Create client and close explicitly in finally block
PubSubClient client = null;
try {
client = PubSubClient.builder()
.address(ADDRESS)
.clientId(CLIENT_ID + "-explicit")
.build();
ServerInfo info = client.ping();
System.out.println("Connected: " + info.getHost());
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
} finally {
if (client != null) {
client.close();
System.out.println("Client explicitly closed.\n");
}
}
}
public void multiClientCloseExample() {
System.out.println("=== Multi-Client Close ===\n");
// Create multiple clients and close in reverse order
PubSubClient pubSubClient = null;
QueuesClient queuesClient = null;
CQClient cqClient = null;
try {
pubSubClient = PubSubClient.builder()
.address(ADDRESS).clientId(CLIENT_ID + "-pubsub").build();
queuesClient = QueuesClient.builder()
.address(ADDRESS).clientId(CLIENT_ID + "-queues").build();
cqClient = CQClient.builder()
.address(ADDRESS).clientId(CLIENT_ID + "-cq").build();
System.out.println("Three clients created.");
pubSubClient.ping();
queuesClient.ping();
cqClient.ping();
System.out.println("All clients connected.\n");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
} finally {
if (cqClient != null) { cqClient.close(); System.out.println("CQClient closed."); }
if (queuesClient != null) { queuesClient.close(); System.out.println("QueuesClient closed."); }
if (pubSubClient != null) { pubSubClient.close(); System.out.println("PubSubClient closed."); }
}
}
public static void main(String[] args) {
CloseExample example = new CloseExample();
example.tryWithResourcesExample();
example.explicitCloseExample();
example.multiClientCloseExample();
System.out.println("\nClose examples completed.");
}
}
How It Works
- All KubeMQ client classes implement
AutoCloseable, sotry-with-resourcesis the preferred pattern — the gRPC channel and any background threads are released automatically when the block exits, even on exception. - The explicit
close()call in afinallyblock is the fallback for long-lived clients that outlive a singletryscope (e.g., Spring beans or background workers). - When closing multiple clients, reverse-construction order (CQClient → QueuesClient → PubSubClient) avoids sending messages on a channel that is already shutting down.
close()is idempotent and safe to call multiple times.
Related
Was this page helpful?