#1
Apache Struts may be a classic in Java web frameworks, but that doesn’t stop it from playing nicely with modern messaging tools like MQTT. Whether you’re building IoT dashboards, real-time chat, or any event-driven app, MQTT brings lightweight messaging into the picture. In this guide, we’ll walk through configuring MQTT in a Struts app—using Docker for development and Kubernetes for production—while keeping your code clean and environment-specific.

1. Add Dependencies in pom.xml

First things first, add the necessary libraries to your pom.xml:
<dependencies>
  <!-- Struts framework -->
  <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>${struts.version}</version>
  </dependency>

  <!-- Paho MQTT client -->
  <dependency>
    <groupId>org.eclipse.paho</groupId>
    <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.2.5</version>
  </dependency>
  
  <!-- Kubernetes client (optional for deployment use) -->
  <dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>${fabric8.version}</version>
  </dependency>
</dependencies>
These libraries give your application messaging power and optional hooks into cloud-native deployment.

2. Run an MQTT Broker with Docker for Development

Let’s set up a simple MQTT broker using Mosquitto in Docker. Create a docker-compose.yml:
version: '3.7'
services:
  mosquitto:
    image: eclipse-mosquitto:latest
    ports:
      - "1883:1883"
      - "9001:9001"  # optional WebSocket port
Then launch it:
docker-compose up -d
Your MQTT broker will now be available at tcp://localhost:1883.

3. Set Up Dev Configuration with mqtt-dev.properties

Create mqtt-dev.properties under src/main/resources:
mqtt.brokerUrl=tcp://localhost:1883
mqtt.clientId=struts-dev-client
mqtt.username=
mqtt.password=
mqtt.topic=dev-topic
In your Struts action or utility class, load these properties:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/mqtt-dev.properties"));

String brokerUrl = props.getProperty("mqtt.brokerUrl");
String clientId = props.getProperty("mqtt.clientId");
// ... username, password, topic

MqttClient client = new MqttClient(brokerUrl, clientId);
client.connect();
client.subscribe(props.getProperty("mqtt.topic"));
This gives you a working MQTT connection during development.

4. Prepare Kubernetes Secrets and ConfigMaps for Production

For Kubernetes-based production, move sensitive data out of your code:
kubectl create secret generic mqtt-secret \
  --from-literal=MQTT_USERNAME=produser \
  --from-literal=MQTT_PASSWORD=prodpass

kubectl create configmap mqtt-config \
  --from-literal=MQTT_BROKER_URL=tcp://mqtt-service:1883 \
  --from-literal=MQTT_CLIENT_ID=struts-prod-client \
  --from-literal=MQTT_TOPIC=prod-topic

5. Create mqtt-prod.properties for Runtime Configuration

Place mqtt-prod.properties in your JAR’s resources directory:
mqtt.brokerUrl=${MQTT_BROKER_URL}
mqtt.clientId=${MQTT_CLIENT_ID}
mqtt.username=${MQTT_USERNAME}
mqtt.password=${MQTT_PASSWORD}
mqtt.topic=${MQTT_TOPIC}
At runtime, environment variables get expanded automatically via Java system properties (or use your preferred configuration strategy).

6. Kubernetes Deployment Snippet

When running in Kubernetes, make sure your Deployment injects the config and secrets:
env:
  - name: MQTT_BROKER_URL
    valueFrom:
      configMapKeyRef:
        name: mqtt-config
        key: MQTT_BROKER_URL
  - name: MQTT_CLIENT_ID
    valueFrom:
      configMapKeyRef:
        name: mqtt-config
        key: MQTT_CLIENT_ID
  - name: MQTT_TOPIC
    valueFrom:
      configMapKeyRef:
        name: mqtt-config
        key: MQTT_TOPIC
  - name: MQTT_USERNAME
    valueFrom:
      secretKeyRef:
        name: mqtt-secret
        key: MQTT_USERNAME
  - name: MQTT_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mqtt-secret
        key: MQTT_PASSWORD
Then your container can boot with:
java -DmqConfig=prod -jar myapp.jar
Choose the right properties file at startup (via environment or system prop), and your Struts app connects to the live MQTT broker.

7. Code Example: Publish or Subscribe

Inside your Struts Action (or helper class), initialize the client nicely:
public class MqttService {
  private final MqttClient client;
  private final String topic;

  public MqttService(Properties props) throws MqttException {
    this.topic = props.getProperty("mqtt.topic");
    this.client = new MqttClient(
      props.getProperty("mqtt.brokerUrl"),
      props.getProperty("mqtt.clientId")
    );
    MqttConnectOptions options = new MqttConnectOptions();
    options.setUserName(props.getProperty("mqtt.username"));
    options.setPassword(props.getProperty("mqtt.password").toCharArray());
    client.connect(options);
  }

  public void publish(String message) throws MqttException {
    client.publish(topic, new MqttMessage(message.getBytes()));
  }

  // add subscribe logic as needed
}
Use this service in your Struts actions or interceptors.

Why This Setup Works

  • Local speed: Docker gives you immediate MQTT feedback for dev testing.
  • Secureprod: Credentials never land in your code—Kubernetes manages them safely.
  • Unified codebase: Same Java and Struts logic works in both dev and prod.
  • Clear separation: mqtt-dev.properties vs. mqtt-prod.properties keeps environments clean.
By combining Docker for local testing, Struts for web logic, and Kubernetes for production-grade configuration, you’ve got a messaging-ready architecture that’s easy to build, test, and deploy. Whether it's real-time dashboards, chat apps, or IoT services, your Struts application can now reliably send and receive MQTT messages with confidence.

image quote pre code