1

I am using JavaSE-1.8 on Windows 10. I have the following unexpected behavior. I am also using Paho Mqtt client, with the server running in a virtual machine.

Setup:

In the main function there is a while loop which loops until a variable terminate_by_mqtt is true. This variable is set when an external client, such as mosquitto_pub on Linux, writes anything to the topic: "terminate"

The following code works as expected:

Main.java:

public class Main{

static Vehicle vehicle;
private static boolean terminate_by_mqtt = false;

public static void main(String[] args) {

    MqttClient client = null;

    try {
        String clientId = "ECU1";
        String broker = "tcp://192.168.56.1:1883";
        client = new MqttClient(broker, clientId);
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setCleanSession(true);
        client.connect(connOpts);
        System.out.println("Connected");
        client.subscribe("terminate");
        client.setCallback(new TopicCallback());
        terminate_by_mqtt = false;

        // ***** This while loop is the symptom ****
        while (true) {
            if(terminate_by_mqtt) break;

            // Works with flush or println. Remove this line and loop hangs
            System.out.flush();
        }
        System.out.println("loop termianted");
        System.out.println("Disconnected");
        System.out.flush(); 

    } catch (MqttException me) {

    }
    // ... Code below (or no code) does not impact the problem
}

static public  synchronized void setTermination(boolean v) {
      terminate_by_mqtt = v;
  }
}

TopicCallback.java implements MqttCallback

The following function handles the callback. Note that this runs on a different thread.

@Override
public void messageArrived(String arg0, MqttMessage msg) throws Exception {
    // TODO Auto-generated method stub
    byte[] bytes = msg.getPayload();
    String x = new String(bytes, "UTF-8");
    System.out.print(x);
    System.out.flush();

 // Causes while loop to terminate if we write to "terminate" topic
    if(arg0.equals("terminate")) {
        Main.setTermination(true);
    }
}

Problem:

As shown in the code, there is a while loop that does not terminate when I set the flag to true. If I add a System.out.flush() in the while loop then there are no issues. If I remove that line, then the while loop does not terminate.

I then tried to debug the program in Eclipse.

  1. Start with no break points
  2. Debug the program
  3. Write using external Mqtt client to "terminate" topic.
  4. Wait. Program does not terminate.
  5. Place break point on the line if(terminate_by_mqtt) break;
  6. After 5, program will break inside the loop and THEN while loop will check for flag and break!

I tried to do some arithmetic operations within the loop, but that did not help solve the problem as System.out.flush() did.

It is as if the code is "ignoring" that line out thinking it will not change (perhaps due to some optimization effort??). I don't know how to prove/ disprove that.

Question:

Any idea what is going on?

Makketronix
  • 1,389
  • 1
  • 11
  • 31

0 Answers0