How to Get Started with HiveMQ MQTT Client in Java
I needed to add MQTT support to a Java application, and I quickly ran into a problem: which library should I use? There are several options available, but many felt outdated or overly complex for my needs. I wanted something modern, well-maintained, and easy to configure.
The Problem with MQTT Client Libraries
When I started researching MQTT clients for Java, I found multiple options:
- Eclipse Paho - The classic choice, but the API felt dated
- Moquette - More of a broker than a client library
- Fuse MQTT Client - Good but limited documentation
I needed a client that supported modern MQTT features (especially MQTT 5), had good documentation, and used a clean, fluent API. After some trial and error, I discovered the HiveMQ MQTT Client.
What Makes HiveMQ MQTT Client Different
The HiveMQ MQTT Client is developed and maintained by the HiveMQ team (the same folks behind the popular MQTT broker). It supports both MQTT 3.1.1 and MQTT 5 protocols, which was important for my project since I wanted to leverage some MQTT 5 features.
What caught my attention was the API design. Instead of dealing with factory classes and configuration objects, it uses a fluent builder pattern that makes the code readable and self-documenting.
Adding the Dependency
First, I needed to add the dependency to my Maven project. The library is available on Maven Central:
<dependency> <groupId>com.hivemq</groupId> <artifactId>hivemq-mqtt-client</artifactId> <version>1.3.12</version></dependency>If you’re using Gradle:
implementation 'com.hivemq:hivemq-mqtt-client:1.3.12'Creating Your First Client
After adding the dependency, I tried creating a simple client. My first attempt looked like this:
Mqtt5AsyncClient client = Mqtt5Client.builder() .identifier("my-client") .serverHost("broker.hivemq.com") .buildAsync();But I immediately got an error - I forgot to specify the port. MQTT uses port 1883 by default for non-TLS connections, and 8883 for TLS connections. Even though there’s a default, being explicit helps avoid confusion:
Mqtt5AsyncClient client = Mqtt5Client.builder() .identifier("my-client-" + UUID.randomUUID()) .serverHost("broker.hivemq.com") .serverPort(1883) .buildAsync();Notice I also changed the client identifier to include a UUID. This is important because MQTT requires unique client identifiers. If you try to connect with an ID that’s already in use, the broker will disconnect the previous client.
Understanding the API Styles
The HiveMQ MQTT Client offers three API styles, which initially confused me. Here’s when to use each:
+----------------+------------------------------------------+| API Style | Best For |+----------------+------------------------------------------+| Blocking | Simple scripts, testing, CLI tools || Asynchronous | Most applications, non-blocking I/O || Reactive | RxJava-based apps, event-driven systems |+----------------+------------------------------------------+For most applications, the asynchronous API is the right choice. It’s non-blocking and returns CompletableFuture objects that you can chain and compose.
Connecting to a Broker
Once I had my client configured, connecting was straightforward:
Mqtt5AsyncClient client = Mqtt5Client.builder() .identifier("my-client-" + UUID.randomUUID()) .serverHost("broker.hivemq.com") .serverPort(1883) .buildAsync();
// Connect to the brokerclient.connect().whenComplete((connAck, throwable) -> { if (throwable != null) { System.err.println("Connection failed: " + throwable.getMessage()); } else { System.out.println("Connected successfully!"); // Start publishing or subscribing here }});The whenComplete callback handles both success and failure cases. In a real application, you’d want more sophisticated error handling and reconnection logic.
Common Mistakes I Made
Mistake 1: Hardcoding Client IDs
Initially, I used a static client ID. This caused issues when running multiple instances of my application:
// DON'T DO THIS - causes conflicts with multiple instances.identifier("my-static-client-id")Mistake 2: Ignoring Port Configuration
I assumed the library would use the default MQTT port, but being explicit prevents surprises:
// ALWAYS specify the port explicitly.serverPort(1883) // or 8883 for TLSMistake 3: Using Blocking API in Web Applications
For a web service, using the blocking API would have blocked threads. The async API integrates much better with modern reactive web frameworks.
Why This Matters
MQTT has become the de facto standard for IoT and real-time messaging. If you’re building applications that need to:
- Communicate with IoT devices
- Implement real-time notifications
- Handle sensor data streams
- Build event-driven microservices
Having a reliable MQTT client in your toolkit is essential. The HiveMQ client gives you that with a modern, well-designed API.
Summary
Getting started with HiveMQ MQTT Client requires just:
- Add the Maven dependency
- Configure client with builder pattern
- Set unique client identifier
- Specify broker host and port
- Choose the right API style for your use case
The library handles the complexity of the MQTT protocol while giving you control over the important configuration options.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments