Connecting MQTT Clients Using Eclipse Paho Java Library and HiveMQ Cloud Broker

Connecting MQTT Clients Using Eclipse Paho Java Library and HiveMQ Cloud Broker

author HiveMQ Team

Written by HiveMQ Team

Category: HiveMQ Cloud HiveMQ

Published: November 3, 2021


This is a getting started guide on connecting MQTT clients to HiveMQ Cloud MQTT Broker using the Eclipse Paho Java Client library. In this post, you will learn how to connect MQTT clients to a HiveMQ Cloud cluster, subscribe to topics, and publish data (sending and receiving messages) using the MQTT protocol.

The Eclipse Paho project provides open-source, mainly client-side, implementations of MQTT and MQTT-SN in a variety of programming languages. The Java client used here supports MQTT V3.1, MQTT V3.1.1, and MQTT V5.

For a completely finished code project, visit our GitHub repository. This example repository is easily and clearly structured to get you started quickly.

Getting Started with HiveMQ Cloud

To start connecting your MQTT clients, you need to set up HiveMQ Cloud. By signing up for HiveMQ Cloud, you will automatically get access to a HiveMQ Cloud Free cluster. HiveMQ Cloud Free is our smallest package that allows you to connect up to 100 MQTT clients for free and test the full MQTT functionality. After signing up, you have a running HiveMQ Cloud cluster, that you can use in this example.

The HiveMQ Cloud Quick Start Guide gives you step-by-step instructions on how to set up your HiveMQ Cloud account, create clusters, and connect MQTT clients.

Prerequisites to Using Eclipse Paho Java Client Library

Create a new project in your local IDE. In the creation steps, select the Gradle project and make sure to activate Kotlin DSL build script, so that the resulting build script will be build.gradle.kts. The project builds automatically with this script and results in a src folder with main and test in it. First, change the dependencies in the mentioned build.gradle.kts. Change your file to look exactly like this, then the Paho Java library will be installed by building your project again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
plugins {
java
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
mavenCentral()
jcenter()
}

dependencies {
testCompile("junit", "junit", "4.12")
implementation("org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2")
implementation("org.bouncycastle:bcprov-jdk15on:1.68")
implementation("org.bouncycastle:bcpkix-jdk15on:1.68")
}

tasks.getByName<Test>("test") {
useJUnitPlatform()
}

Adding HiveMQ Cloud MQTT Broker Credentials

To connect your Paho Java client with your HiveMQ Cloud cluster, your host name, username and password are needed. These will be used in the code example in the next section. The host name can be found in the Details section of the Overview tab of your cluster.

cluster overview

After the cluster is created, add a set of credentials as shown in the picture below in the MQTT Credentials section of the Access Management tab of your cluster. You can use them in this example and future implementations. Use any secure username and password you desire. The client credentials that you just created are the values needed for the username and password variables.

credentials

Code Example on Securely Connecting an MQTT Client to HiveMQ Cloud

This example project covers the core functionality of an MQTT client interacting with HiveMQ Cloud. To securely connect the MQTT client with HiveMQ Cloud you need to enable TLS. Use your username and password to authenticate your MQTT client at HiveMQ Cloud. To connect the client, use the port 8883, which is standard for secure MQTT communication.

First open the main folder, that was mentioned earlier, and create a new Java class in the java folder. Name this file Example.java. Here the code snippets below will be added.

Now import the required libraries, including the Paho Client library, and an SSL library that is used for a secure connection. This is done by adding the following import statements in your Example.java file.

1
2
3
4
5
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import javax.net.ssl.SSLSocketFactory;
import java.util.Arrays;
import static java.nio.charset.StandardCharsets.UTF_8;

After these import statements, put your main method inside the public Example class, that was created when making the file earlier. This method starts by creating the MqttClient. When connecting to your HiveMQ Cloud cluster, you want to use a secure connection. For that reason, SSL is used in the serverURI. Exchange the placeholder for the hostname with your HiveMQ Cloud hostname to complete the address and connect to your cluster.

Add the credentials that you used for the cluster creation earlier into the placeholders for username and password. As mentioned, we want to use SSL, so it is activated here as well.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class Example {
    public static void main(String[] args) throws MqttException {
        MqttClient client = new MqttClient(
            "ssl://<your_host>:8883", // serverURI in format: 
            // "protocol://name:port"
            MqttClient.generateClientId(), // ClientId
            new MemoryPersistence()); // Persistence

        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName("<your_username>");
        mqttConnectOptions.setPassword("<your_password>".toCharArray());
        // using the default socket factory
        mqttConnectOptions.setSocketFactory(SSLSocketFactory.getDefault()); 
        client.connect(mqttConnectOptions);

Now you can set a few callbacks, to make it easier to track certain events. In this example we set a callback for when the client lost the connection to the broker. Another callback we add is a callback for messages that are received by the client. We also register a callback for when an outgoing publish is complete. These are printed to the console.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
client.setCallback(new MqttCallback() {

    @Override
    // Called when the client lost the connection to the broker
    public void connectionLost(Throwable cause) { 
        System.out.println("client lost connection " + cause);
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) {
        System.out.println(topic + ": " + Arrays.toString(message.getPayload()));
    }

    @Override
    // Called when an outgoing publish is complete
    public void deliveryComplete(IMqttDeliveryToken token) { 
        System.out.println("delivery complete " + token);
    }
});

The code subscribes to the topic filter "#".
This enables the MQTT client to receive all messages that are published to this topic filter. The so-called wildcard ("#"), that is used here as the topic filter, includes all topics.

1
client.subscribe("#", 1); // subscribe to everything with QoS = 1

Then the code publishes a message to the topic "topic" with the content "payload".

1
2
3
4
5
client.publish(
        "topic",
        "payload".getBytes(UTF_8),
        2, // QoS = 2
        false);

It prints the content (payload) of the message due to the messageArrived callback, that gets triggered when a message is received. Other callbacks in this example are connectionLost and deliveryComplete, that get called when their respective event occurs.

At the end, the client is disconnected.

1
client.disconnect();

In a real-world implementation for example, you could send temperature data with the messages and the messageArrived callback could print the temperature to an external display that may be connected through Wi-Fi. When the connection is lost, you could set up a notification to your phone, so you can repair it quickly. In this context deliveryComplete could ensure that your system works normally and all message are actually published. You can see that this kind of cloud-hosted MQTT is perfect for DIY home automation and smart home applications.

Finally, here is the whole code in one paragraph:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
* Copyright 2021 HiveMQ GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import javax.net.ssl.SSLSocketFactory;
import java.util.Arrays;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Example {
    public static void main(String[] args) throws MqttException {
        MqttClient client = new MqttClient(
            "ssl://<your_host>:8883", // serverURI in format: "protocol://name:port"
            MqttClient.generateClientId(), // ClientId
            new MemoryPersistence()); // Persistence

        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName("<your_username>");
        mqttConnectOptions.setPassword("<your_password>".toCharArray());
        mqttConnectOptions.setSocketFactory(SSLSocketFactory.getDefault()); // using the default socket factory
        client.connect(mqttConnectOptions);

        client.setCallback(new MqttCallback() {
        
            @Override
            // Called when the client lost the connection to the broker
            public void connectionLost(Throwable cause) { 
                System.out.println("client lost connection " + cause);
            }
        
            @Override
            public void messageArrived(String topic, MqttMessage message) {
                System.out.println(topic + ": " + Arrays.toString(message.getPayload()));
            }
        
            @Override
            // Called when an outgoing publish is complete
            public void deliveryComplete(IMqttDeliveryToken token) { 
                System.out.println("delivery complete " + token);
            }
        });

        client.subscribe("#", 1); // subscribe to everything with QoS = 1

        client.publish(
                "topic",
                "payload".getBytes(UTF_8),
                2, // QoS = 2
                false);

        client.disconnect();
    }
}

Get Started on MQTT and Eclipse Paho Java Client

If you want to learn more about MQTT, visit the MQTT Essentials guide. It explains the core MQTT concepts, features and other essential information. To learn more about Paho-Java, visit the official website of the eclipse foundation.

author HiveMQ Team

About HiveMQ Team

We love writing about MQTT, IoT protocols and architecture in general. Our experts are here to help, so reach out to us if we can help!

mail icon Contact HiveMQ
newer posts HiveMQ and Tatsoft to Power Modern IIoT Systems
Strong Adoption of MQTT in IIoT older posts