Java is a powerful, platform-independent language commonly used for enterprise applications, Android development, and IoT platforms. The Eclipse Paho project provides a robust Java MQTT client that can be used to connect to MQTT brokers over TCP or WebSocket, with support for TLS and authentication.
This guide walks you through building a Java MQTT client using the Eclipse Paho Java library. It also outlines MQTT connection flows, publishing/subscribing to topics, and cleanly disconnecting.
Before you begin, ensure you have the following set up:
This section covers multiple ways to connect to an MQTT broker using Java. Make sure you have the broker details (hostname, port, username/password, CA certificate) handy.
Basic TCP Connection
import org.eclipse.paho.client.mqttv3.*;
String broker = "tcp://broker-url:1883";
String clientId = "testclient";
MqttClient client = new MqttClient(broker, clientId, new MemoryPersistence());
client.connect();
Connect with Authentication
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("username");
options.setPassword("password".toCharArray());
client.connect(options);
Connect over TLS/SSL
String broker = "ssl://broker-url:8883"; // Note: use `ssl://` scheme
MqttConnectOptions options = new MqttConnectOptions();
options.setSocketFactory(SSLSocketFactoryGenerator.getSocketFactory("ca.crt")); // custom helper method
client.connect(options);
Connect via WebSocket
String broker = "ws://broker-url:8080/mqtt"; // Or "wss://" for secure WebSocket
MqttClient client = new MqttClient(broker, clientId, new MemoryPersistence());
client.connect();
String topic = "test/topic";
String content = "{\"temperature\": 50.5, \"humidity\": 34}";
int qos = 1;
MqttMessage message = new MqttMessage(content.getBytes());
message.setQos(qos);
client.publish(topic, message);
client.subscribe("test/topic", 1);
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable cause) {
// handle disconnect
}
public void messageArrived(String topic, MqttMessage message) {
System.out.println("Message received:\n\t" + topic + " -> " + new String(message.getPayload()));
}
public void deliveryComplete(IMqttDeliveryToken token) {
// not used for subscriptions
}
});
To unsubscribe:
client.unsubscribe("test/+");
Clean disconnection ensures the broker releases resources tied to the session and avoids lingering socket connections.
client.disconnect();
client.close();
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import javax.net.ssl.SSLSocketFactory;
import java.nio.charset.StandardCharsets;
public class MqttClient4Example {
// --- MQTT Broker Configuration ---
private static final String BROKER_HOST = "tcp://mqtt-broker-URL:1883"; // Replace with your broker URL
private static final boolean AUTHENTICATION = true;
private static final String USERNAME = "Username";
private static final String PASSWORD = "Password";
private static final boolean ENCRYPTION = false; // Set true to enable TLS
private static final String CLIENT_ID = "testclient4";
private static final String TOPIC = "test/topic";
public static void main(String[] args) {
try {
// --- Create MQTT Client ---
MqttClient client = new MqttClient(BROKER_HOST, CLIENT_ID, new MemoryPersistence());
// --- Configure Connection Options ---
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
if (AUTHENTICATION) {
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
}
if (ENCRYPTION) {
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
options.setSocketFactory(sslSocketFactory);
}
// --- Set Callbacks ---
client.setCallback(new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) {
System.out.println("Received message on topic '" + topic + "': " + new String(message.getPayload()));
}
});
// --- Connect to Broker ---
client.connect(options);
// --- Subscribe to a Topic ---
client.subscribe(TOPIC, 1);
// --- Wait briefly to ensure subscription is registered ---
Thread.sleep(2000);
// --- Publish a Test Message ---
String payload = "{\"temperature\": 50.5, \"humidity\": 34}";
MqttMessage message = new MqttMessage(payload.getBytes(StandardCharsets.UTF_8));
message.setQos(1);
message.setRetained(false);
client.publish(TOPIC, message);
// --- Wait to allow delivery ---
Thread.sleep(3000);
// --- Disconnect from Broker ---
client.disconnect();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Save this sample code as:
MqttClient4Example.java
Compile:
javac -cp .:org.eclipse.paho.client.mqttv3-1.2.5.jar MqttClient4Example.java
Execute:
java -cp .:org.eclipse.paho.client.mqttv3-1.2.5.jar MqttClient4Example
import org.eclipse.paho.mqttv5.client.MqttAsyncClient;
import org.eclipse.paho.mqttv5.client.MqttConnectionOptions;
import org.eclipse.paho.mqttv5.client.IMqttToken;
import org.eclipse.paho.mqttv5.client.MqttCallback;
import org.eclipse.paho.mqttv5.client.persist.MemoryPersistence;
import org.eclipse.paho.mqttv5.common.MqttMessage;
import org.eclipse.paho.mqttv5.common.MqttException;
import java.nio.charset.StandardCharsets;
public class MqttClient5Example {
private static final boolean AUTHENTICATION = true;
private static final String USERNAME = "Username";
private static final String PASSWORD = "Password";
public static void main(String[] args) {
String broker = "tcp://mqtt-broker-URL:1883";
String clientId = "testclient5";
String topic = "test/topic";
try {
// Create client and options
MqttAsyncClient client = new MqttAsyncClient(broker, clientId, new MemoryPersistence());
MqttConnectionOptions options = new MqttConnectionOptions();
options.setCleanStart(true);
if (AUTHENTICATION)
{
options.setUserName(USERNAME);
options.setPassword(PASSWORD.getBytes(StandardCharsets.UTF_8));
}
// Set callback for connection, message arrival, etc.
client.setCallback(new MqttCallback() {
@Override
public void disconnected(org.eclipse.paho.mqttv5.client.MqttDisconnectResponse disconnectResponse) {
System.out.println("Disconnected: " + disconnectResponse.getReasonString());
}
@Override
public void mqttErrorOccurred(MqttException exception) {
System.out.println("MQTT Error: " + exception.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) {
System.out.println("Message arrived on topic '" + topic + "': " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttToken token) {
System.out.println("Delivery complete for message with ID: " + token.getMessageId());
}
@Override
public void connectComplete(boolean reconnect, String serverURI) {
System.out.println("Connected to " + serverURI + (reconnect ? " (reconnect)" : ""));
}
@Override
public void authPacketArrived(int reasonCode, org.eclipse.paho.mqttv5.common.packet.MqttProperties properties) {
// No-op for now
}
});
// Connect client
IMqttToken connectToken = client.connect(options);
connectToken.waitForCompletion();
System.out.println("Connected!");
Thread.sleep(3000);
// Subscribe to topic
IMqttToken subToken = client.subscribe(topic, 1);
subToken.waitForCompletion();
System.out.println("Subscribed to: " + topic);
// Publish a message
String payload = "{\"temperature\": 50.5, \"humidity\": 34}";
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(1);
IMqttToken pubToken = client.publish(topic, message);
pubToken.waitForCompletion();
System.out.println("Published message: " + payload);
// Wait to receive messages (sleep for demo)
Thread.sleep(3000);
// Disconnect and close
client.disconnect();
client.close();
System.out.println("Disconnected and closed client.");
} catch (MqttException | InterruptedException e) {
e.printStackTrace();
}
}
}
Save this sample code as:
MqttClient5Example.java
Compile:
javac -cp .:org.eclipse.paho.mqttv5.client-1.2.5.jar MqttClient5Example.java
Execute:
java -cp .:org.eclipse.paho.mqttv5.client-1.2.5.jar MqttClient5Example.java