MQTT Client Library Encyclopedia – Eclipse Paho Java

Eclipse Paho
Language Java
Website http://www.eclipse.org/paho/
API-Style Synchronous and Asynchronous
License Eclipse Public License

Description

Eclipse Paho is an umbrella project for several MQTT and MQTT-SN client implementations in different programming languages. The Eclipse Paho project was one of the first open source MQTT client implementations available and is actively maintained by a huge community. Paho also features a Java client which is suited for embedded use, Android applications and Java applications in general. The initial code base was donated to Eclipse by IBM in 2012.

The Java version of Eclipse Paho is rock-solid and is used by a broad range of companies from different industries around the world to connect to MQTT brokers. The synchronous/blocking API of Paho makes it easy to implement the applications MQTT logic in a clean and concise way while the asynchronous API gives the application developer full control for high-performance MQTT clients that need to handle high throughput. The Paho API is highly callback based and allows to hook in custom business logic to different events, e.g. when a message is received or when the connection to the broker was lost. Paho supports all MQTT features and a secure communication with the MQTT Broker is possible via TLS.

Features

MQTT 3.1
MQTT 3.1.1 ok
LWT ok
SSL/TLS ok
Automatic Reconnect ok
Disk Persistence ok
QoS 0 ok
QoS 1 ok
QoS 2 ok
Authentication ok
Throttling nok
Offline Message Buffering ok

Usage

Installation

The Java Paho library is available as .jar file from the project page and can be used without any further dependencies by including it to your Java classpath.

The most convenient way to install Paho is to use a dependency management tool like Maven, Gradle or Ivy. The following examples use Maven but it should be trivial to port that to Gradle or Ivy. Paho isn’t available in Maven Central, so the following repository has to be added to your pom.xml:

<repositories>
    <repository>
        <id>Eclipse Paho Repo</id>
        <url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
    </repository>
</repositories>

Now you can add the following to your dependencies section in order to download Paho:

<dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.0.2</version>
</dependency>

Creating a client object

All MQTT operations are exposed via a MqttClient object. Before connecting, publishing or subscribing, the user needs to create an instance of this MqttClient first.

MqttClient client = new MqttClient( 
    "tcp://broker.mqttdashboard.com:1883", //URI 
    MqttClient.generateClientId(), //ClientId 
    new MemoryPersistence()); //Persistence

A MqttClient always needs an URL and a client identifier in order to be able to connect to a MQTT broker. Please note that Paho expects the connection String to be a valid URI and you need to specify the protocol first (in our case TCP). It’s also required to specify the port you want to connect to. The MQTT client identifier needs to be unique (if you’re not familiar with the client identifier concept of MQTT, read this blog post about MQTT connection establishment), in the example we’re using a utility method from Paho to generate a client identifier for temporary usage. Since we don’t want to persist the state of pending QoS messages and the persistent session we are just using a in-memory persistence. If you omit this parameter, a file-based persistence is used by default.

Please note, that after the creation of the MqttClient you need to connect to the broker first before you are able to do any MQTT operation.

Connect

After obtaining a MqttClient object, connecting to a MQTT broker is very easy:

client.connect();

The client is now connected. You can check if the client is already connected by using

client.isConnected()

Connect with MQTT 3.1 or MQTT 3.1.1

Depending which MQTT broker you are using, you may want to explicitely connect with a specific MQTT version. If you’re not sure which version to use, read this blog post about MQTT version differences.

By default, Paho tries to connect with MQTT 3.1.1 and falls back to MQTT 3.1 if it’s not possible to connect with 3.1.1.
Connecting with a specific version is easy:

MqttConnectOptions options = new MqttConnectOptions();

options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
// options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);

client.connect(options);

We need to create a MqttConnectOptions object first and set the specific version. When connecting, we need to pass this MqttConnectOptions object to the client in order to use it.

Connect with LWT

In order to use MQTTs Last-Will-and-Testament feature, we can also use a MqttConnectOptions object as we have seen above:

MqttConnectOptions options = new MqttConnectOptions();

options.setWill( 
    "topic", // topic 
    "payload".getBytes(UTF_8), // payload 
    2, // QoS 
    false); // retained?
client.connect(options);

We need to specify all relevant LWT data like the topic, the payload of the message, the Quality of Service level and if this message should be a retained message.

Connect with Username / Password

Paho also supports authentication via username / password

MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("username");
options.setPassword("password".toCharArray());
client.connect(options);

While the username needs to be a string, the password is passed to the MqttConnectOptions object as char array.

Publish

After connecting to a MQTT broker, a typical action is to publish a MQTT message. With Paho this is pretty straightforward with this one-liner:

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

We can control all relevant MQTT information like the topic, the payload, the Quality of service and if the message should be retained. Paho expects you to connect to the MQTT broker first, otherwise you’ll receive a MqttException.

Publish a retained Message

Publishing a retained message is very simple. You only need to set the retained parameter of the publish method to true:

client.publish( "topic", // topic 
    "payload".getBytes(UTF_8), // payload 
    2, // QoS 
    true); // retained

Subscribe

In order to receive messages a client must subscribe to one or more MQTT topics with the desired QoS level. If you want to react on incoming MQTT messages, you need to set a callback first. This callback is called on specific events, e.g. when a message arrives.

client.setCallback(new MqttCallback() {

            @Override
            public void connectionLost(Throwable cause) { //Called when the client lost the connection to the broker 
            }

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

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {//Called when a outgoing publish is complete 
            }
        });
        
client.connect();
client.subscribe("#", 1);

It’s important to note that the callback needs to be set before the client connects to the MQTT broker, otherwise you could lose messages, especially after resuming a persistent session.

To subscribe to messages, you can use the method subscribe, which takes a topic and a QoS level as parameter. There is also an overloaded subscribe method available if you want to subscribe to more than one MQTT topic at once.

Unsubscribe

Unsubscribing from specific topics is straightforward:

client.unsubscribe("#");

There is also an overloaded unsubscribe method available which lets you unsubscribe from several MQTT topics at once.

Disconnect

Sometimes MQTT clients need to disconnect gracefully. This is also straightforward with Paho:

client.disconnect();

The disconnect method will wait until all pending operations (like pending QoS 2 messages) are finished before sending the MQTT DISCONNECT message. There is an overloaded method which allows you to set the timeout manually if you don’t like the default timeout (30 seconds).

Using TLS / SSL

Paho supports SSL by using the standard Java SocketFactory approach. The code below is not complete but you will get the idea how SSL / TLS is set up with Paho.

MqttClient client = new MqttClient("ssl://yourbroker:8883", MqttClient.generateClientId(), new MemoryPersistence());

SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = readKeyStore();
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

MqttConnectOptions options = new MqttConnectOptions();
options.setSocketFactory(sslContext.getSocketFactory());

client.connect(options);

You first need to specify “SSL” as protocol for the connection string (also note the port 8883 which is standard for secure MQTT), so Paho is aware of the fact that you want to connect with a secure communication channel. You then need to provide a SSLSocketFactory and pass it to the MqttOptions object. If specifying a TrustManagerFactory, you can connect to trusted MQTT brokers, even with self-signed certificates.

Since Paho uses standard Java SSL mechanisms, you can also use e.g. BouncyCastles or other security libraries which may provide better APIs than the default JDK APIs.

Author Information

BH8C3195-final-web
Dominik Obermaier | dc-square GmbH
Dominik Obermaier is co-founder and CTO at dc-square. He designs high scalability server software for the distributed and mobile world and his main interests are IoT, M2M communication, MQTT and highly scalable software on the JVM. He is a frequent conference speaker and writes articles for several magazines.
   Website

2 comments

  1. Marc Cenac says:

    The latest Paho Java client now has Automatic Reconnect and Offline Message Buffering: http://www.eclipse.org/paho/clients/java/

    You can find the PR here:
    https://github.com/eclipse/paho.mqtt.android/pull/68

    1. Hallo Marc,
      thank you for the information.
      The feature table has been updated.
      Regards,
      Florian, from the HiveMQ Team.

Leave a Reply

Your email address will not be published. Required fields are marked *