Git Product home page Git Product logo

paho.mqtt.java's Introduction

Eclipse Paho Java Client

Build Status

The Paho Java Client is an MQTT client library written in Java for developing applications that run on the JVM or other Java compatible platforms such as Android

The Paho Java Client provides two APIs: MqttAsyncClient provides a fully asynchronous API where completion of activities is notified via registered callbacks. MqttClient is a synchronous wrapper around MqttAsyncClient where functions appear synchronous to the application.

Project description:

The Paho project has been created to provide reliable open-source implementations of open and standard messaging protocols aimed at new, existing, and emerging applications for Machine-to-Machine (M2M) and Internet of Things (IoT). Paho reflects the inherent physical and cost constraints of device connectivity. Its objectives include effective levels of decoupling between devices and applications, designed to keep markets open and encourage the rapid growth of scalable Web and Enterprise middleware and applications.

Links

Using the Paho Java Client

Downloading

Eclipse hosts a Nexus repository for those who want to use Maven to manage their dependencies. The released libraries are also available in the Maven Central repository.

Add the repository definition and the dependency definition shown below to your pom.xml.

Replace %REPOURL% with either https://repo.eclipse.org/content/repositories/paho-releases/ for the official releases, or https://repo.eclipse.org/content/repositories/paho-snapshots/ for the nightly snapshots. Replace %VERSION% with the level required .

The latest release version is 1.2.5 and the current snapshot version is 1.2.6-SNAPSHOT.

** Dependency definition for MQTTv3 client **

<project ...>
<repositories>
    <repository>
        <id>Eclipse Paho Repo</id>
        <url>%REPOURL%</url>
    </repository>
</repositories>
...
<dependencies>
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
        <version>%VERSION%</version>
    </dependency>
</dependencies>
</project>

** Dependency definition for MQTTv5 client **

<project ...>
<repositories>
    <repository>
        <id>Eclipse Paho Repo</id>
        <url>%REPOURL%</url>
    </repository>
</repositories>
...
<dependencies>
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>org.eclipse.paho.mqttv5.client</artifactId>
        <version>%VERSION%</version>
    </dependency>
</dependencies>
</project>

If you find that there is functionality missing or bugs in the release version, you may want to try using the snapshot version to see if this helps before raising a feature request or an issue.

Building from source

There are two active branches on the Paho Java git repository, master which is used to produce stable releases, and develop where active development is carried out. By default cloning the git repository will download the master branch, to build from develop make sure you switch to the remote branch: git checkout -b develop remotes/origin/develop

To then build the library run the following maven command: mvn package -DskipTests

This will build the client library without running the tests. The jars for the library, source and javadoc can be found in the following directories:

org.eclipse.paho.client.mqttv3/target
org.eclipse.paho.mqttv5.client/target

Documentation

MQTTv3 reference documentation is online at: http://www.eclipse.org/paho/files/javadoc/index.html

Log and Debug in the Java Client: https://wiki.eclipse.org/Paho/Log_and_Debug_in_the_Java_client

Getting Started

The included code below is a very basic sample that connects to a server and publishes a message using the MQTTv3 synchronous API. More extensive samples demonstrating the use of the MQTTv3 and MQTTv5 Asynchronous API can be found in the org.eclipse.paho.sample directory of the source.

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

public class MqttPublishSample {

    public static void main(String[] args) {

        String topic        = "MQTT Examples";
        String content      = "Message from MqttPublishSample";
        int qos             = 2;
        String broker       = "tcp://iot.eclipse.org:1883";
        String clientId     = "JavaSample";
        MemoryPersistence persistence = new MemoryPersistence();

        try {
            MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
            System.out.println("Connecting to broker: "+broker);
            sampleClient.connect(connOpts);
            System.out.println("Connected");
            System.out.println("Publishing message: "+content);
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            sampleClient.publish(topic, message);
            System.out.println("Message published");
            sampleClient.disconnect();
            System.out.println("Disconnected");
            System.exit(0);
        } catch(MqttException me) {
            System.out.println("reason "+me.getReasonCode());
            System.out.println("msg "+me.getMessage());
            System.out.println("loc "+me.getLocalizedMessage());
            System.out.println("cause "+me.getCause());
            System.out.println("excep "+me);
            me.printStackTrace();
        }
    }
}

paho.mqtt.java's People

Contributors

andypiper avatar aploese avatar bisk1 avatar ctron avatar david-katz avatar desokroshan avatar dobermai avatar henry-lp avatar hmvp avatar hylkevds avatar icraggs avatar jarthorn avatar jpwsutton avatar maxpagani avatar mcarrer avatar miketran78727 avatar msqr avatar ogis-yamazaki avatar orpiske avatar pavelanikeichyk avatar powturns avatar rdasgupt avatar redboltz avatar rehanshaukat avatar satyadeepk avatar silh avatar sp193 avatar surmay avatar vit21ik avatar zyyangbj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paho.mqtt.java's Issues

Class not found exception when using code obfuscation

migrated from Bugzilla #461267
status RESOLVED severity normal in component MQTT-Java for 1.1
Reported in version 1.2 on platform PC
Assigned to: James Sutton

On 2015-03-03 03:31:11 -0500, Ste Sem wrote:

Hi. I'm using the Paho library inside an Android app.

When I set the build option "minifyEnabled" to true (to obfuscating the code) I get
java.util.MissingResourceException: Error locating the logging class
when running the app.

This is caused by:
https://github.com/eclipse/paho.mqtt.java/blob/master/org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/logging/LoggerFactory.java

logger = getLogger(loggerClassName, ResourceBundle.getBundle(messageCatalogName), loggerID, null);

When "minifyEnabled" is set to true, the compiler changes class names.
So please don't use class names in paho library

On 2015-05-28 10:09:08 -0400, Alexis GENET wrote:

-dontobfuscate don't change anything.

Any idea ?

On 2015-05-28 10:13:52 -0400, Benjamin Cabé wrote:

I didn't have a close look but it looks like this line in LoggerFactory.java:

private static String jsr47LoggerClassName = "org.eclipse.paho.client.mqttv3.logging.JSR47Logger";

should probably be something like

private static String jsr47LoggerClassName = JSR47Logger.getName();

no?

On 2015-07-01 03:20:42 -0400, Alexis GENET wrote:

Seem to be resolved by adding :
-keep class org.eclipse.paho.client.mqttv3.logging.JSR47Logger {
*;
}

On 2015-07-28 11:06:38 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/52727

On 2015-07-28 11:20:28 -0400, Ian Craggs wrote:

Assigning to James.

On 2015-07-28 11:25:48 -0400, James Sutton wrote:

I've submitted Change 52727 which will implement Benjamin's fix. By using JSR47Logger.class.getName() we avoid using the hard-coded string which would not match the obfuscated class name during minification.

On 2015-07-28 11:26:34 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/52727 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 30ace5e

NullPointer on MqttToken.internalTok

migrated from Bugzilla #470718
status VERIFIED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform Other
Assigned to: Ian Craggs

On 2015-06-22 10:16:27 -0400, Armin Reisch wrote:

java.lang.NullPointerException: Attempt to read from field 'org.eclipse.paho.client.mqttv3.internal.Token org.eclipse.paho.client.mqttv3.MqttToken.internalTok' on a null object reference
at org.eclipse.paho.client.mqttv3.internal.ClientState.notifyResult(ClientState.java:1015)
at org.eclipse.paho.client.mqttv3.internal.ClientState.notifyReceivedAck(ClientState.java:856)
at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:118)
at java.lang.Thread.run(Thread.java:818)

Stacktrace was sent to me automatically. Can't see any case when this field might be NULL from code. Any idea?

On 2015-07-28 06:46:11 -0400, Ian Craggs wrote:

Hello. Is it possible to take a trace?

https://wiki.eclipse.org/Paho/Log_and_Debug_in_the_Java_client

Thanks

On 2015-08-03 10:37:30 -0400, Armin Reisch wrote:

(In reply to Ian Craggs from comment # 1)

Hello. Is it possible to take a trace?

https://wiki.eclipse.org/Paho/Log_and_Debug_in_the_Java_client

Thanks

Hi Ian,

we haven't seen this crash in our development, but we see 50 crashes during the last two weeks for our customers. Cause it is a automated crash report from 'hockeyapp', we do not have more info than the stacktrace.

What kind of traces would be helpful? Logging for a special class?

Thanks

On 2015-08-06 06:52:48 -0400, Ian Craggs wrote:

What version of the Java client library is being used? The line numbers don't match the source I've looked at so far.

It looks like this will occur if the client receives an MQTT ack for which there is no corresponding message in its local store. This should not normally happen. It could occur if the server is not implementing MQTT correctly, or if there were overlapping QoS 1 flows (I'm not sure if this should ever really occur). In any case, we should handle the condition. This statement:

MqttToken token = tokenStore.getToken(ack);

in ClientState.notifyReceivedAck() will set token to null if the originating message of the ack is not in the client store. We should check for token being null. If it is, we should record the fact in the trace, and skip the processing in the rest of notifyReceivedAck.

On 2015-08-06 07:15:04 -0400, Ian Craggs wrote:

I've added a fix to the develop branch. The build tests have run successfully:

https://hudson.eclipse.org/paho/job/paho-java-dev-nightly/626/

On 2015-10-07 11:20:09 -0400, Armin Reisch wrote:

We currently use the 1.0.2 version of Paho on client side. For server side Mosquitto (1.4.2) is used.
I cherry picked your commit on developer branch to our current version and it is working fine for now.
Thanks for your help and the explanation.

Client object not set in onSuccess callback

migrated from Bugzilla #469527
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-06-05 16:31:23 -0400, Ian Craggs wrote:

The token returned to onSuccess after connect returns null for getClient().

On 2015-06-05 18:11:52 -0400, Ian Craggs wrote:

Fix added to development branch.

Hang when application does not return from MessageArrived promptly

migrated from Bugzilla #476036
status NEW severity normal in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-08-27 08:21:16 -0400, Ian Craggs wrote:

Reported by: Jason Blakely. [email protected]

So I did more looking and some debugging and tracing since - even you acks solution seems to hang.

So using the ver 1.0.0 paho code (since hangs still happen) I did some tcpdump tracing using wireshark and paho tracing and some print statements in paho code itself. I still think the hang is because of the ACK/RST TCP received by Paho and the handling of the error.

This is what I see when the hang occurs:
-- CommsSender.java handleRunException method calls ClientComms.java shutdownConnection method
-- ClientComms.java shutdownConnection method calls CommsReceiver stop method
-- CommsReceiver stop method does a join on the receive thread and hangs

I am unsure who is suppose to stop the receiving thread so the join does NOT hang.
I did try putting an argument in the join (see code below) to only wait a few seconds and not hang - and it seems to work ok (as far as i can tell ) and continue receiving messages. Although the connectionLost metthod in my MqttCallback message handler class is never called. Also lots of duplicate messages are received as I have mentioned in my previous note.

if (!Thread.currentThread().equals(recThread)) {
try {
// Wait for the thread to finish.
recThread.join(3000);
}
catch (InterruptedException ex) {
}
}

here is the wireshark screen capture of the traffic to server on a linux client.

this is the corresponding paho trace : [attachment "paho0.log.0.linux.wireshark" deleted by Ian Craggs/UK/IBM]

here is the paho trace on windows: [attachment "paho0.log.0.windows1" deleted by Ian Craggs/UK/IBM]

Now on the duplicate messages received when a connections closes: seems like most of the messages should have been acked already ?
here is my client log of messages received (this is with my change with the receive thread join) - [attachment "switchbox.log.windows2" deleted by Ian Craggs/UK/IBM]

below is a sample line from this file -- first field is my seq num of each msg handled, ignore t=0, Evt=nnnn where nnnn the seq num of the publish order i put this in the message during publish to help with dups. Notice after each tcp conn reset the pub order seq dups

298 t=0 Evt=1254_files.file.comment.updated id=5e1c30fe-5760-4574-9f8e-47ccc6588293 actor=_PublishTestActor orgID=20001050 ts[2015-08-11 06:29:12.310] now[2015-08-12 09:55:57.506]

Note: a little while back - i put in a hack in my client to restart MqttClient if the hang happens. I supplied my own logger to Paho
LoggerFactory.setLogger("com.ibm.switchbox.test.SwitchboxTest$SwitchboxLogger");
which looked for the particular Timed out as no activity severe log entry and restart MqttClient -- when i did this only two messages were dups !!!

On 2015-08-27 08:52:51 -0400, Ian Craggs wrote:

Notes:

  1. It was the design intention of the MessageArrived callback that it be returned from promptly. It was never intended to work correctly if the application did spend a significant amount of time in it.

  2. I made an enhancement to the API to notionally allow MessageArrived processing to take a long time in this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=472172. This actually means that MessageArrived must be returned from quickly but the acks are delayed until another method is called.

Jason, you say this: "even you acks solution seems to hang." Yes this is true if you still spend a relatively "long" time in MessageArrived. Did you change your application to not spend any time in MessageArrived? Because if you didn't, the fix to bug 472172 won't fix your problem. The key question: is the approach outlined in bug 472172 a solution that would be satisfactory for you, if it did work? I mean from the external API point of view. Are you happy to not spend a long time in MessageArrived, and allow the ack to be sent by calling a separate method.

Is the real core of your request to be able to spend as long as you want in the MessageArrived callback?

I really need to focus on the external behavior rather than the internal call sequence of the client library, because a fix for one use case might not be appropriate for all circumstances. I want to understand the problem from the API/application point of view so we make sure we fix all cases that might occur, not just one.

On 2015-08-27 10:34:38 -0400, jason blakely wrote:

the hang seems to have nothing to do with the amount of time spent in MessageArrived. The problem is the handling of the connection reset. Paho handling of the reset eventually tries to do a join of a thread that does not end!

On 2015-09-08 20:38:57 -0400, jason blakely wrote:

Have not seen any update on this. A fix is needed for the hang. No product should just hang and not have any way to let the client know there is a hang. There must be a logic error in the way Paho handles the connection reset to cause this hang. Please investigate more to discover the error.

Correct documentation regarding deletion of retained message

migrated from Bugzilla #483544
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: James Sutton

On 2015-12-03 05:03:15 -0500, Jaume Teixi wrote:

In the Class MqttMessage documentation

https://www.eclipse.org/paho/files/javadoc/org/eclipse/paho/client/mqttv3/MqttMessage.html

Instead of:
"Sending a message with the retained set to false will clear the retained message from the server."

It should say something like:
"Sending a message with the retained set to: true and an empty byte array as payload: new byte[0] will clear the retained message from the server."

On 2015-12-07 09:17:55 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/62103

On 2015-12-07 10:07:48 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/62103 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: f21837e

HTTP headers should be case-insensitive for websockets

migrated from Bugzilla #482187
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform PC
Assigned to: James Sutton

On 2015-11-13 19:52:26 -0500, Tristam MacDonald wrote:

HTTP headers are case-insensitive by spec, but the newly-minted (and much anticipated) WebSockets implementation in Paho treats headers as case-sensitive, causing websocket upgrade to fail if the server returns lowercase headers.

On 2015-11-16 06:36:21 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/60487

On 2015-11-16 06:48:45 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/60487 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: ccdd522

On 2015-11-16 19:35:09 -0500, Tristam MacDonald wrote:

One missing toLowerCase() call on the HTTP_HEADER_UPGRADE. See comment on Gerrit.

On 2015-11-17 05:09:50 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/60588

On 2015-11-17 05:12:52 -0500, James Sutton wrote:

Thanks for spotting that Tristam, I've put another change in (https://git.eclipse.org/r/#/c/60588/) to resolve this. As Ian pointed out, the numerous toLowerCase() calls were unnecessary so I've just set the headers to be lower case anyway. This means that if we needed to add another header check in the future, there is less chance of making the same mistake.

On 2015-11-17 05:34:40 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/60588 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: b2ff952

No paho sources published in maven release repo

migrated from Bugzilla #474126
status ASSIGNED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform PC
Assigned to: James Sutton

On 2015-08-03 05:08:11 -0400, Davy De Waele wrote:

Paho maven releases repo does not contain sources.

Despite the snapshot repo having sources, the release repo does not, making it cumbersome to attach Paho sources in an IDE.

On 2015-08-12 07:57:25 -0400, Ian Craggs wrote:

This is true. There was an obstacle to achieving this when I last created a new service release of the Java client, but I can't remember what it was. We'll look at this when creating a new service release.

Connect onSuccess getting executed for the second when connection closed by server

migrated from Bugzilla #434761
status RESOLVED severity normal in component MQTT-Java for 0.9
Reported in version unspecified on platform PC
Assigned to: Bin Zhang

On 2014-05-13 10:29:41 -0400, Shankar karuppiah wrote:

MqttAsyncClient connect onSuccess getting executed for the second time when connection closed by server.

mqtt.connect -> connect onSuccess executed -> 5s -> server disconnects the socket -> connect onSuccess executed for 2nd time

On 2014-08-20 05:39:38 -0400, Bin Zhang wrote:

Yes, you are right. Not necessary 5s, it seems it happened any time the server close the connection.

I will fix this issue.

On 2014-08-22 04:59:22 -0400, Shankar karuppiah wrote:

Thanks you :)

On 2014-08-29 04:03:53 -0400, Bin Zhang wrote:

Fixed in develop branch via https://git.eclipse.org/r/#/c/32519/

On 2014-11-10 21:22:02 -0500, Bin Zhang wrote:

*** Bug 449877 has been marked as a duplicate of this bug. ***

On 2015-09-09 04:41:37 -0400, Mirko Kohns wrote:

HI, I am running on the current master branch.
This bug was fixed in August 2014 in develop branch.
Since then .. serveral version were released.
Why is the fix not in the current master?

On 2015-09-09 04:51:03 -0400, Mirko Kohns wrote:

(In reply to Mirko Kohns from comment # 5)

HI, I am running on the current master branch.
This bug was fixed in August 2014 in develop branch.
Since then .. serveral version were released.
Why is the fix not in the current master?

Soory, tomatoes on my eyes.
Commit IS in current branch!
Sorry!

Duplicate Message Id 631 in logcat.properties

migrated from Bugzilla #466853
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-05-08 11:19:38 -0400, Ian Craggs wrote:

A recent update created a duplicate message id in logcat.properties.

The file isn't sorted which makes it difficult to determine whether an id is already used.

On 2015-05-08 12:31:51 -0400, Ian Craggs wrote:

Changed message id to 643. Sorted message file.

[feature] Pluggable network protocols for a new Java client

migrated from Bugzilla #433835
status NEW severity normal in component MQTT-Java for ---
Reported in version future on platform PC
Assigned to: James Sutton

On 2014-04-30 06:50:35 -0400, Ian Craggs wrote:

Having pluggable network protocols for a Java client would allow websockets http/socks proxy support. The pluggable approach is probably best suited to a new refactored Java client based on Java 6.

On 2015-11-02 11:40:54 -0500, Ian Craggs wrote:

Correcting component and assignee.

Logging greatly degrades performance of un/subscribe() methods

migrated from Bugzilla #469417
status ASSIGNED severity normal in component MQTT-Java for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-06-04 13:59:53 -0400, Pierre-Luc Lacroix wrote:

I was running a test where I was sending 100k topic filters simultaneously to my broker and noticed it was taking forever. I believe you could hit the same issue by using multiple VERY long topic filters.

Had a quick look at the code and it was quite obvious to me what the problem was here:

public IMqttToken unsubscribe(String[] topicFilters, Object userContext, IMqttActionListener callback) throws MqttException { final String methodName = "unsubscribe"; String subs = ""; for (int i=0;i0) { subs+=", "; } subs+=topicFilters[i];
  // Check if the topic filter is valid before unsubscribing
  // Although we already checked when subscribing, but invalid
  // topic filter is meanless for unsubscribing, just prohibit it
  // to reduce unnecessary control packet send to broker.
  MqttTopic.validate(topicFilters[i], true/*allow wildcards*/);

}

//@TRACE 107=Unsubscribe topic={0} userContext={1} callback={2}
log.fine(CLASS_NAME, methodName,"107",new Object[]{subs, userContext, callback});

We are creating an immensely long string containing all subscriptions simply for logging purposes.

I can come up with two fixes:

  1. Only generate that string if the logging level is fine or lower.
  2. Truncate the string after N characters (stop appending at some point)

I believe other methods are also affected by this issue (e.g.: subscribe(String[] topicFilters, int[] qos, Object userContext, IMqttActionListener callback))

On 2015-06-05 06:47:54 -0400, Ian Craggs wrote:

Thanks Pierre-Luc. I can see why this would be a problem. Out of interest, are you using the long topic just for testing, or in a "real" application?

On 2015-06-05 07:31:29 -0400, Pierre-Luc Lacroix wrote:

(In reply to Ian Craggs from comment # 1)

Thanks Pierre-Luc. I can see why this would be a problem. Out of interest,
are you using the long topic just for testing, or in a "real" application?

This was discovered while testing.

WebSocket handles frames over 125 byte incorrectly

migrated from Bugzilla #482432
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version future on platform PC
Assigned to: James Sutton

On 2015-11-17 19:56:00 -0500, Tristam MacDonald wrote:

The WebSockets implementation incorrectly reads the extended payload length bytes, and only reads the first 16 KB of large packets.

In WebSocketFrame.java ( https://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/tree/org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketFrame.java?h=develop ):

  • Need to reset payloadLength to zero if byteCount is > 0 before the loop at line 147.
    (because the value of the initial 7 bits is replaced by the length encoded in the
    extended payload length bytes, not added to)
  • Comparison needs to be >= in the while loop at line 147.
    (currently this does not read the final byte of the extended payload length)
  • Need to call InputStream.read() in a loop until payloadLength bytes have been read at line 160.
    (read returns a maximum of 16 KB in one call, returns the number of bytes read)

On 2015-11-24 11:27:03 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/61159

On 2015-11-25 05:05:20 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/61159 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 513a77a

Allow more control over when acks are sent in response to incoming messages

migrated from Bugzilla #472172
status RESOLVED severity enhancement in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-07-08 09:33:57 -0400, Ian Craggs wrote:

Sometimes an application would like more control over when the MQTT acknowledgments are sent in response to incoming PUBLISH packets.

To enable this, I propose:

setManualAcks(boolean):

to tell the client whether to send the acks at the successful completion of the messageArrived callback. The default is false, which is the current behaviour, so existing applications will not be affected.

messageArrivedComplete(int messageId, int Qos)

this call must be made to acknowledge the incoming messages. If it is not, then things will go wrong!

On 2015-07-08 09:35:16 -0400, Ian Craggs wrote:

And yes, I do have a first pass implementation ready to go. Checking into the development branch now...

On 2015-08-06 06:24:36 -0400, Ian Craggs wrote:

For information, if you hang around in the messageArrived callback too long, it can cause the keepAlive processing to time out with this message:

Jul 26, 2015 10:07:24 AM org.eclipse.paho.client.mqttv3.internal.ClientState checkForActivity
SEVERE: test2_20001050: Timed out as no activity, keepAlive=60,000 lastOutboundActivity=1,437,919,464,750 lastInboundActivity=1,437,919,500,505 time=1,437,919,644,790 lastPing=1,437,919,524,763

Update Contributing guidelines

Now that this repository has been moved to GitHub, the Contributing process needs updating. The Main Readme could also do with a revamp.

There was a bug when we used the Eclipse Paho MQTT Utility to publish the message when we selected a image

migrated from Bugzilla #477535
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform PC
Assigned to: James Sutton

Original attachment names and IDs:

On 2015-09-16 04:46:37 -0400, Henry Zhu wrote:

After opening the Eclipse Paho MQTT Utility, we found that there was a bug when we used the Eclipse Paho MQTT Utility to publish the message when we selected a image file. The binary which was sent to the MQTT server was not the binary but the string format of binary. Meanwhile, the binary format is correct if we used the command which was provided by mosquitto using the below command, for example mosquitto_pub.exe -h 192.168.80.196 -p 1884 -f C:\temp\1.png -t test1

On 2015-09-16 04:49:30 -0400, Henry Zhu wrote:

Created attachment 256609
Eclipse Paho MQTT Utility issue

On 2015-11-16 10:26:42 -0500, James Sutton wrote:

The behaviour isn't what I would expect either, I've had a look in the source, looks like the file reader simply tries to read the file as UTF-8 and if it fails, it reads the file in as a byte array but converts it to HEX.

I propose that we add another Checkbox to the UI called 'Raw' that allows the user to choose between the file being sent as HEX or as a raw byte array (Which to me would be the expected behaviour)

When the file is read in, we should keep it as the byte array internally and then only convert it to hex if the user ticks the box. Though we should keep the byte array in case they change their minds.

On 2015-11-16 10:27:19 -0500, James Sutton wrote:

Created attachment 257977
Mockup showing the raw check box

ClientState.checkForActivity() does not attach callback to IMqttToken before it is placed on event queue.

migrated from Bugzilla #473928
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

On 2015-07-30 09:15:43 -0400, James Sutton wrote:

In the Android client in AlarmPingSender.onReceive(), when sending a ping, a callback is created with the function of releasing the WAKE_LOCK that is acquired when the ping is sent.

However the callback is attached to the Token after it has been requested. If the AlarmPingSender thread is running slower than the main network thread then the client could get into a situation where the Token has been processed, the ping sent and ACKed before the callbacks have been attached to it.

This would result in a WAKE_LOCK never being released which would be detrimental to the phone's battery life as it would not be able to sleep.

On 2015-07-30 09:31:23 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/52859

On 2015-07-30 09:36:00 -0400, James Sutton wrote:

I've submitted Change 52859 which implements the fix described by [email protected] in the mailing list where this issue was first raised.

On 2015-07-30 11:30:01 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/52859 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 1130f00

[feature] Automatic Reconnect and Offline Buffering

migrated from Bugzilla #486843
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version future on platform All
Assigned to: James Sutton

On 2016-01-29 10:48:02 -0500, James Sutton wrote:

Copied from here: #9

Automatic Reconnect and Disconnected Publishing Plan

Currently, the Paho Java client is lacking two major areas of functionality: Automatic Reconnect and Disconnected (or Offline) Publishing.
The goal is to implement these features in time for the next release Neon.

This issue aims to outline the plan for adding this new functionality into the client and has been modeled off Mike Tran's plan and work for the same functionality in the Javascript Client.

Recap: Possible Client States

There are 5 main potential states that the client can be in. The User will usually desire the client to either be in the connected or disconnected states.

never connected: This is the initial state of the client where:
The client has not yet sent a connect request.
The client has never received a CONNACK after it's initial connect request.
connecting: A connect request is in progress.
connected: The client is connected and ready to send and receive messages.
disconnecting: A disconnect request is in progress.
disconnected: The client goes from connected to disconnected state when:
A disconnect request has been completed
As a result of a networking error, or the server is no longer reachable.

What does it do?

Automatic Reconnect

Will automatically attempt to reconnect to the broker (or one of the servers in the host list) while the client is in disconnected state.

The client will not perform automatic reconnection if it is not in disconnected state.
When the connection is list, the connectionLost() callback is called before the client starts the reconnect process. Since the state of the client is disconnected, the application is allowed to call the connect function with new connection options if they wish.
When disconnect is called while connected, the client goes to the disconnected state and automatic reconnect is disabled.
If the client application calls connect after it had reconnected, an invalid state error will be thrown.
The client library does not subscribe for the application after it successfully reconnects. A callback will be provided to notify the application when it has been reconnected allowing it to make any subscriptions to topics itself.
Disconnected Publishing

Will allow the client to save messages in a buffer whilst the client is in the disconnected state.

Once the client is reconnected (To the same or different broker), the buffered messages are scheduled to be sent.
To maintain order of messages, the client library must send buffered messages before sending new messages.
The client library does not save any messages while the client is in the never connected state. So it cannot send any messages before it connects for the first time.
When disconnect is called while connected, the client goes to disconnected state and Disconnected Publishing remains active if enabled.
API Changes

Automatic Reconnect

The following optional attributes will be added to the the MqttClient and MqttAsyncClient classes:

setReconnect(boolean reconnect) : If true, the client will attempt to reconnect. Default: False
setReconnectTimeInterval(int reconnectTimeInterval) : Time interval in seconds between reconnect attempts. Default: 10
Note: In the Javascript client, these attributes are in the Connection Options object, however in the Java client, they need to be in the Client classes to allow the developer to change them after conect() has been called.

The following change will be made to the MqttCallback Interface:

connectionLost(Throwable cause, boolean reconnect) : If the reconnect boolean is true, the client will perform automatic reconnection whilst it is disconnected.
Addition of a new callback connectionComplete(boolean reconnect). This would not replace the existing IMqttToken that you get if you call connectWithResult (So that we don't break any functionality). However it would serve the same purpose, it would be called every time that the client connects or reconnects to the broker. This will allow the application to re-make any subscriptions that were lost or to send any held messages if it is not using Disconnected Publishing. The boolean reconnect attribute is set to true if the connection was the result of an automatic reconnection, else it is false.
Disconnected Publising

To maintain the order of the messages, the client must ensure that buffered messages are scheduled to be sent before new messages.
The following optional attributes will be added to the MqttClient and MqttAsyncClient classes:

boolean setDisconnectedPublishing : If present and true, the client will store messages whilst disconnected. Default: False
int setDisconnectedBufferSize : The maximum number of messages that will be stored in memory while the client is disconnected. Default: 5000
boolean setPersistDisconnectedBuffer : If true, the client will persist the messages to disk, if false or not present, the messages will only be saved in memory. Default: False
getBufferedMessagesCount : Returns the number of messages in the buffer.
deleteBufferedMessage(int index) : Deletes the buffered message at the index location.
The following change will be made to the MqttClient and MqttAsyncClient classes:

publish : Currently throws an MqttException. If the buffer is full, this will be thrown containing a message explaining that the Message buffer is full.
Sample application

Example 1

This application wants to use both Automatic Reconnect and Disconnected Publising. The Application does not want to persist buffered messages.

public static void main( String[] args )
{

    String topic        = "/greenhouse/temperature";
    String broker       = "tcp://iot.eclipse.org:1883";
    String clientId     = "TemperatureMonitor_42";
    MemoryPersistence persistence = new MemoryPersistence();

    try {
        MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setCleanSession(true);

        sampleClient.setCallback(new MqttCallback() {

            public void messageArrived(String topic, MqttMessage message) throws Exception {
                // Not used
            }

            public void deliveryComplete(IMqttDeliveryToken token) {
                // Not used
            }

            public void connectionLost(Throwable cause, boolean reconnect) {
                System.out.println("Connection Lost: " + cause.getMessage());
                if(reconnect){
                    System.out.println("Client will attempt to automatically reconnect");
                }
            }

            public void connectionComplete(boolean reconnect) {
                // Make or re-make subscriptions here
                if(reconnect){
                    System.out.println("Automatically Reconnected to Broker!");
                } else {
                    System.out.println("Connected To Broker for the first time!");
                }
            }
        });


        sampleClient.setReconnect(true);  // Enable Automatic Reconnect
        sampleClient.setReconnectTimeInterval(30);  // Attempt to reconnect every 30 seconds
        sampleClient.setDisconnectedPublishing(true);  // Enable Disconnected Publishing
        sampleClient.setDisconnectedBufferSize(1000);  // Only Store 1000 messages in the buffer
        sampleClient.setPersistDisconnectedBuffer(false);  // Do not persist the buffer


        System.out.println("Connecting to broker: "+broker);
        sampleClient.connect(connOpts);
        System.out.println("Connected");


        /*
         * Sample code to continually publish messages
         */
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                // Publish the current Temperature
                String temp = String.format("%.2f", getTemperature());
                System.out.format("Publising temperature %s to topic %s. ", temp, topic);
                MqttMessage message = new MqttMessage(temp.getBytes());
                message.setQos(0);
                try {
                    sampleClient.publish(topic, message);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
        }, 5000, 5000);  // Every 5 seconds



    } catch(MqttException me) {
        System.out.println("reason "+me.getReasonCode());
        System.out.println("msg "+me.getMessage());
        System.out.println("loc "+me.getLocalizedMessage());
        System.out.println("cause "+me.getCause());
        System.out.println("excep "+me);
        me.printStackTrace();
    }
}

Before I start work on this, I'd be very interested in hearing back from the community. Because of the very nature of the features that need to be implemented, it means adding a lot to the API which would mean a small amount of work for developers upgrading their application to use Neon (For example the addition of a callback to MqttCallback). If anyone can spot anything that might cause issues down the line, or thinks that there might be a better way of accomplishing this functionality please do comment!

Null pointer in Paho Java client WebSocket classes

migrated from Bugzilla #484264
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform PC
Assigned to: James Sutton

On 2015-12-11 17:39:12 -0500, Kamil Baczkowicz wrote:

Hi,

While testing mqtt-spy 0.4.0 beta with a snapshot version
(1.0.3-20151116.050526-315) of the Paho Java client, I keep getting a null pointer:

2015-12-10 23:43:20,821 INFO [MqttAsyncConnectionRunnable ] -
Connecting client ID [mqttspy] to server [[ws://broker.hivemq.com]];
options =
============== Connection options ==============
CleanSession : true
SocketFactory : null
MqttVersion : 0
KeepAliveInterval : 60
ConTimeout : 30
UserName : null
SSLProperties : null

WillDestination : null

2015-12-10 23:43:22,444 WARN [MqttConnectionResultHandler ] -
Connecting to [email protected] failed
MqttException (0) - java.lang.NullPointerException
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:633)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.receiveHandshakeResponse(WebSocketHandshake.java:97)
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.execute(WebSocketHandshake.java:66)
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketNetworkModule.start(WebSocketNetworkModule.java:76)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:619)
... 1 more

This is when I incorrectly configure the port. So I believe for ws://
it defaults to 1883 or 80, but the actual WebSockets broker is on 8000
in that situation.

I tried that with test.mosquitto.org and when I specify the incorrect
port of 80, I get the same:

2015-12-10 23:56:35,784 INFO [MqttAsyncConnectionRunnable ] -
Connecting client ID [mqttspy] to server
[[ws://test.mosquitto.org:80]]; options =
============== Connection options ==============
CleanSession : true
SocketFactory : null
MqttVersion : 0
KeepAliveInterval : 60
ConTimeout : 30
UserName : null
SSLProperties : null

WillDestination : null

2015-12-10 23:56:36,110 WARN [MqttConnectionResultHandler ] -
Connecting to [email protected]:80 failed
MqttException (0) - java.lang.NullPointerException
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:633)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.receiveHandshakeResponse(WebSocketHandshake.java:103)
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketHandshake.execute(WebSocketHandshake.java:66)
at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketNetworkModule.start(WebSocketNetworkModule.java:76)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:619)
... 1 more

Cheers,
Kamil

On 2015-12-14 06:23:51 -0500, James Sutton wrote:

The WebSocket client needs to fail safely when it does not get the response it expects. In this case it's opening a TCP port and sending an HTTP handshake. When it receives either nothing or data it does not expect it will fall over in this way.

I'm adding a null check that will throw an IOException with a message along the lines of "Invalid response, server may not support websockets".

I'll also change the default port behaviour when no port is provided. Although not everyone uses it, port 80 is the default port for WebSockets so I think that should be default if none is chosen as it's likely that most users would expect that.

On 2015-12-14 06:30:19 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/62606

On 2015-12-17 17:03:47 -0500, Kamil Baczkowicz wrote:

Thanks James!

Is that fix going to be available as a 1.0.3-SNAPSHOT build at https://repo.eclipse.org/content/repositories/paho-snapshots/org/eclipse/paho/org.eclipse.paho.client.mqttv3/1.0.3-SNAPSHOT/?

On 2015-12-18 03:41:00 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/62606 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: d796504

Introduce a new interface IMqttCallback to replace MqttCallback which dosen't follow the naming conversion

migrated from Bugzilla #445059
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version unspecified on platform All
Assigned to: Bin Zhang

On 2014-09-25 05:26:31 -0400, Bin Zhang wrote:

MqttCallback is an interface and it is a part of the Paho Java client public API, but it dosen't follow the naming conversion.
It is supposed to have 'I' as the prefix. Introduce a new interface IMqttCallback to replace MqttCallback, and deprecate the old one MqttCallback.

On 2014-09-25 06:41:36 -0400, Dave Locke wrote:

The reason the interface name was left without the I naming convention was to maintain backward compatibility with existing applications. If the interface name is changed and the old one removed then all applications will need to be modified and recompiled.

On 2015-01-19 22:45:53 -0500, Bin Zhang wrote:

No, what i mean is just let MqttCallback extends IMqttCallback, and move all methods to IMqttCallback, and documented MqttCallback as deprecated, using IMqttCallback instead later on.

It will not break the backward compatibility, nothing is needed to be changed for the existing applications.

On 2015-06-02 10:22:46 -0400, Ian Craggs wrote:

I'm going to set this to won't fix, as there are plenty more urgent tasks.

Sync to Maven central

migrated from Bugzilla #460942
status RESOLVED severity normal in component MQTT-Java for 1.1
Reported in version future on platform All
Assigned to: James Sutton

On 2015-02-26 08:56:40 -0500, Obermaier Dominik wrote:

In order to make it easier for developers to add Paho to their projects, Paho releases should be synced to Maven central.

Most build tools automatically try to download resources from Maven central and this would also have the advantage that no separate entry in the repositories section of a maven pom.xml is needed anymore. Another huge advantage is, that if companies use a Nexus / Artifactory proxy repository, the Paho repository does not need to be added to the proxy repo but can be downloaded directly without any problems and further configurations.

The feedback I got from some people at conferences and other events where I talked about Paho was, that the Fusesource client is easier to initially install, mainly because of the lack of a Maven central sync of Paho. Since the Maven deployment process seems to be in place now, this would be a good opportunity to also add this to the release process.

On 2015-08-12 05:13:27 -0400, Ian Craggs wrote:

We'll look into this.

On 2015-11-09 06:48:03 -0500, James Sutton wrote:

I've raised this bug against Hudson to which they've set us up with Maven central.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=479549

As we are already publishing artifacts to the eclipse repository, I'm currently investigating how to publish to Maven central as well. Once I've done this I'll report back.

On 2015-11-13 09:21:50 -0500, James Sutton wrote:

To clarify on this. Do we want to sync just releases to Maven central, or releases & snapshots too?

On 2015-12-04 11:22:31 -0500, James Sutton wrote:

Currently trying to get a single build working that deploys to just OSSRH.

https://hudson.eclipse.org/paho/job/paho-java-maven-test/14/console

Looks, like files aren't being signed correctly and some files are missing, i.e. sources.

On 2015-12-04 11:39:11 -0500, James Sutton wrote:

Ok, the files are now being signed by the maven-gpg-plugin.

These are the remaining errors preventing the files reaching staging:

[ERROR] Rule failure while trying to close staging repository with ID "orgeclipsepaho-1001".
[ERROR]
[ERROR] Nexus Staging Rules Failure Report
[ERROR] ==================================
[ERROR]
[ERROR] Repository "orgeclipsepaho-1001" failures
[ERROR] Rule "javadoc-staging" failures
[ERROR] * Missing: no javadoc jar found in folder '/org/eclipse/paho/org.eclipse.paho.mqtt.utility/1.0.2'
[ERROR] Rule "sources-staging" failures
[ERROR] * Missing: no sources jar found in folder '/org/eclipse/paho/org.eclipse.paho.mqtt.utility/1.0.2'
[ERROR] Rule "pom-staging" failures
[ERROR] * Invalid POM: /org/eclipse/paho/java-parent/1.0.2/java-parent-1.0.2.pom: Developer information missing
[ERROR]
[ERROR]
[ERROR] Cleaning up local stage directory after a Rule failure during close of staging repositories: [orgeclipsepaho-1001]
[ERROR] * Deleting context 3e4bc7c08ea566.properties
[ERROR] Cleaning up remote stage repositories after a Rule failure during close of staging repositories: [orgeclipsepaho-1001]
[ERROR] * Dropping failed staging repository with ID "orgeclipsepaho-1001" (Rule failure during close of staging repositories: [orgeclipsepaho-1001]).

Looks like the javadoc / sources issues could be the same as the ones affecting the eclipse repo so it will be good to fix these.

Invalid POM should be easy enough to fix. I'll find out how much information is required then will push that to the master branch.

On 2015-12-07 08:21:39 -0500, James Sutton wrote:

From: https://bugs.eclipse.org/bugs/show_bug.cgi?id=479549#c11

"I've commented the ossrh ticket to state that you've done your first release. People at sonatype will now activate the sync to maven central and you should be done. Next time you will do a new release, this will be done automatically."

Once this has happened, we should be done. I'll check that a sample app with the maven central repo defined in it's POM works then I'll resolve this bug.

On 2015-12-09 04:11:59 -0500, James Sutton wrote:

This work has now been completed and Paho Java 1.0.1 is now available on Maven Central.

http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.eclipse.paho%22

This means that you no longer have to define the eclipse repository in your POM files.

Now that this process has been made automatic, we will continue to release to Maven central as well as the eclipse repository from now on. This does not include SNAPSHOT releases, which will remain in the eclipse repo only.

CommsReceiver disconnecting on unknown PUBREC

migrated from Bugzilla #462474
status UNCONFIRMED severity normal in component MQTT-Java for 1.1
Reported in version unspecified on platform PC
Assigned to: Bin Zhang

On 2015-03-18 10:57:11 -0400, Martijn Stellinga wrote:

Whenever the CommsReceiver class receiver an MqttAck message, the class looks for the token of the originally published message, and if it is not found, it throws an exception (CommsReceiver line 123).

Unfortunately, we have a production system where our application crashed, resulting in our MQTT broker (mosquitto) sending a PUBREC message for a message that is not known in the application anymore.
Because the CommReceiver throws an exception, it disconnects.
Unfortunately, because the PUBREC is never acknowledged, Mosquitto keeps sending the PUBREC message every time the application tries to connect. We can only solve this by clearing the Mosquitto message database, meaning we lose any other valid messages that are still queued.

It seems it would be more robust if the Commsreceiver acknowledges PUBREC messages, even if it does not have a token for them, and logs a warning.

On 2015-03-19 03:09:00 -0400, Bin Zhang wrote:

Per my understanding, the use case is:

Client publishes a message with QoS2, and server receives this message and replies with PUBREC, but client can never acknowledge this PUBREC because it cannot find a stored PUBLISH with the same packet ID.

I think the client shouldn't discard the message util it received PUBREC, so at this time, the client is the message owner. It should consider the message hasn't arrived the server, and should resend the PUBLISH message again. It probably means the client data store is corrupted. And I don't understand why the server will keep sending the PUBREC, unless it receives another PUBLISH from client. because the ownership of the message hasn't been transferred to the server yet.

And yes, i agree the it would be more robust if just acknowledge PUBREC in this case.
but I'm not sure if it's a good idea. But at least i think we need to make sure the client store not lose any QoS1&2 messages even it crashes.

cc Ian, WDYT?

On 2015-11-02 11:00:45 -0500, Maarten van Schouwenburg wrote:

I may have found a situation where this can occur, without the client data store being corrupted.

If the Paho client sends a PUBLISH with the dup flag set, at the exact same time the server sends the PUBREC, the server (mosquitto) will respond to the second message too. Which results in 2 PUBREC messages being send.

If we just ignore the fact that this one unknown and just call clientState.notifyReceivedAck((MqttAck)message); we may get another duplicate message on PUBCOMP

excerpt from mosquitto.log:

1446478939: Received PUBLISH from backend1 (d0, q2, r0, m49638, '/v1/account/xxxxx/devices/xxxxxx/status', ... (103 bytes))
1446478939: Sending PUBREC to backend1 (Mid: 49638)
1446478959: Received PUBLISH from backend1 (d1, q2, r0, m49638, '/v1/account/xxxxx/devices/xxxxxx/status', ... (103 bytes))
1446478959: Sending PUBREC to backend1 (Mid: 49638)
1446478959: Sending PUBREC to backend1 (Mid: 49638)
1446478972: Received PUBREL from backend1 (Mid: 49638)
1446478972: Sending PUBCOMP to backend1 (Mid: 49638)
1446478973: Received PUBREL from backend1 (Mid: 49638)
1446478973: Sending PUBCOMP to backend1 (Mid: 49638)

Need new methods to unsubscribe

migrated from Bugzilla #476056
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform PC
Assigned to: James Sutton

On 2015-08-27 10:46:54 -0400, Mike Tran wrote:

In bug 466579 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=466579), new subscribe methods were added:

subscribe(String, int, IMqttMessageListener)
subscribe(String, int, Object, IMqttActionListener, IMqttMessageListener)
subscribe(String[], int[], IMqttMessageListener)
subscribe(String[], int[], Object, IMqttActionListener, IMqttMessageListener)

Currently, the unsubscribe methods are:
unsubscribe(String topicFilter);
unsubscribe(String[] topicFilters);
unsubscribe(String topicFilter, Object userContext, IMqttActionListener callback);
unsubscribe(String[] topicFilters, Object userContext, IMqttActionListener callback);

I propose to add these new unsubscribe methods:
unsubscribe(String, IMqttMessageListener)
unsubscribe(String, Object, IMqttActionListener, IMqttMessageListener)
unsubscribe(String[], IMqttMessageListener)
unsubscribe(String[], Object, IMqttActionListener, IMqttMessageListener)

And add corresponding unsubscribe methods for the synchronous client.

On 2015-09-04 05:05:57 -0400, Ian Craggs wrote:

Mike, the existing unsubscribe methods remove any existing message listener associated with a subscription, so we don't need to specify the message listener in the unsubscribe method.

Timed out as no activity

严重: 2015112400010098: Timed out as no activity, keepAlive=60,000 lastOutboundActivity=1,453,796,759,368 lastInboundActivity=1,453,796,700,033 time=1,453,796,819,375 lastPing=1,453,796,759,368

WebSocket support for the Java client

migrated from Bugzilla #459142
status RESOLVED severity enhancement in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: James Sutton

On 2015-02-04 10:10:10 -0500, Ian Craggs wrote:

On 31/01/15 08:45, Benjamin Cabé wrote:
I�ve been asked recently on Twitter if Paho supports for MQTT over WebSockets. I wonder if this is something that was planned for future releases? FWIW it doesn�t look like a big deal to implement judging by this existing project (based on Paho) I found on GH:

https://github.com/inventit/mqtt-websocket-java
https://github.com/inventit/mqtt-websocket-java/blob/master/src/main/java/io/inventit/dev/mqtt/paho/WebSocketNetworkModule.java

Maybe the author would be willing to contribute to Paho? :-)

On 2015-02-04 11:11:38 -0500, Bin Zhang wrote:

I just have a quick look at the source, and I think we may need get rid of the dependency on eclipse jetty.

On 2015-02-25 23:51:16 -0500, Yasith Lokuge wrote:

Hi, I would like to contribute eclipse MQTT project as my Google Summer of Code project. Looking forward to hear from you. Regards!

On 2015-03-01 21:59:52 -0500, Bin Zhang wrote:

Paho java client has zero dependency, i don't think it's good idea to bring a big dependency on eclipse jetty.

And what's the use case for mqtt websocket java client ?

On 2015-03-02 08:06:13 -0500, Ian Craggs wrote:

Bin,

I think the use case is to traverse firewalls, without having to open up another port specifically for MQTT.

I have previously implemented WebSockets support in Python (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.testing.git/tree/interoperability/mqtt/broker/start.py) -- so it's not too hard to it without depending on any external libraries.

On 2015-03-02 21:15:50 -0500, Bin Zhang wrote:

Ok, +1

Hi Yasith Lokuge, please remove any external dependencies if you are happy to contribute.

On 2015-09-15 12:04:22 -0400, Nicholas Grabowski wrote:

+1 as well.

Corporate firewalls is the use case.

On 2015-09-16 06:59:24 -0400, James Sutton wrote:

+1, sounds like a really useful enhancement!

On 2015-09-17 10:25:37 -0400, Val Zu wrote:

Besides simplifying the firewall design and allowing our clients to use our applications from within their corporate firewalls, say at work, initiating connection to the MQTT broker over web socket from Java may be advantageous when MQTT broker affinity/stickiness is desired the same way how we can stick to a web server.

In the environment where MQTT broker is collocated with a web server, the cookie returned by the web server and used by the load balancer to route subsequent HTTP requests to that same web server may be used by the load balancer to also route the web socket connection to the MQTT broker running on that box or in that cluster/data center.

Such arrangement may eliminate the need to cluster the MQTT broker, and may reduce network utilization in the data center having to duplicate messages across all MQTT brokers.

On 2015-09-17 10:32:57 -0400, Ian Craggs wrote:

Assigning to James.

James, can you take a look and evaluate how much work this is please?

On 2015-09-17 12:58:09 -0400, Nicholas Grabowski wrote:

I did a little research into the code and this looks like what needs to be done.

....

Adding WebSockets to paho java client

Summary:
Can easily be done by extending and without modification to the existing codebase. Simply update the paho Android Service to include the 4 changes listed below or create a new "Android WebSocket" project. It will probably contain 3 src files + configuration:

1.) Import an Andriod compatible Websocket library (e.g. atmosphere/wasync)

2.) Extend the MqttAsyncClient.java class. Override the createNetworkModule method. Add a new "case" WebSocketNetworkModule.java

3.) Create a WebSocketNetworkModule.java which implements NetworkModule. This is where you create the HTTP(S) based WebSocket using the imported library.

4.) Extend the MqttClient.java as well. Replace MqttAsyncClient.java reference with new.MqttAsyncClient.java

On 2015-09-18 10:33:33 -0400, James Sutton wrote:

Thanks Nicholas,

I'm actually implementing the Websocket stuff myself as it's fairly trivial to do and means we can stay dependency free.

You're right about where to put it though, Extending / Implementing a NetworkModule definitely seems the way to go.

On 2015-09-23 09:53:38 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/56527

On 2015-09-24 06:50:19 -0400, James Sutton wrote:

To use websockets in the java client with these changes, simply add either ws (for unsecured) or wss (for secured) as the protocol in the server uri.

For instance:
ws://localhost:1883
or
wss://localhost:1883

On 2015-09-24 10:04:50 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/56527 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: d24aaff

On 2015-09-24 11:27:23 -0400, Nicholas Grabowski wrote:

Awesome news. We'll test in the next few weeks and get back to you if we see any issues.

On 2015-09-25 04:30:42 -0400, James Sutton wrote:

Delivered and now available in the SNAPSHOT repository.

On 2015-10-06 04:55:15 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/57495

On 2015-10-08 04:46:05 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/57495 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 461d6c5

On 2015-11-13 17:02:51 -0500, Geoff Wakefield wrote:

Hello,

I am seeing the java client crash when subscribed to a topic over web sockets, then receiving json in the payload that contains the fields "userId" or "password". Was this intended?

Thanks,
Geoff Wakefield

On 2015-11-14 01:11:12 -0500, Geoff Wakefield wrote:

Please disregard my previous comment. Oddly, this issue is actually that I can't seem to receive a payload larger than 77 bytes without an error occurring and a lost connection at the subscriber end. I am trying to see if it is something specific to my environment.
Thanks.

Disconnection upon subscribing to # channel

Hi,
I see client disconnections upon subscription to # channel on an Apache Apollo broker.

Disconnection exception is:

 MqttException null
MqttException (0) - java.io.EOFException
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage.decodeUTF8(MqttWireMessage.java:344)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish.<init>(MqttPublish.java:62)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage.createWireMessage(MqttWireMessage.java:189)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage.createWireMessage(MqttWireMessage.java:163)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream.readMqttWireMessage(MqttInputStream.java:83)
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:107)
    at java.lang.Thread.run(Thread.java:785)
Caused by: java.io.EOFException
    at java.io.DataInputStream.readFully(DataInputStream.java:208)
    at java.io.DataInputStream.readFully(DataInputStream.java:180)
    at org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage.decodeUTF8(MqttWireMessage.java:340)
    ... 6 more```

client.getServerURI() returns wrong URI when servers are configured thru connect options

migrated from Bugzilla #481097
status CLOSED severity normal in component MQTT-Java for 1.2
Reported in version unspecified on platform PC
Assigned to: James Sutton

On 2015-10-30 06:46:51 -0400, Gnanaskandan R wrote:

Hi,

First up, I'd like to thank all the people on the project for the great work! I ran into an issue today and I would like to report it.

I am using ActiveMQ as my MQTT broker. I have set it up with master-slave configuration. Hence, I do this in my Paho client:

String[] servers = {"tcp://localhost:1883","tcp://localhost:1893"};
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(servers);
client.connect(options);

The connect method correctly identifies which URI to use and connects appropriately. However, the MQTTClient mandates a ServerURI in its constructor and that is the URI that is returned when I invoke client.getServerURI(). This is the issue and I am unable to see the actual URI that the client is connected to.

I am sure connection is established because I killed the master broker.

Thanks,
Gnanas.

On 2015-11-06 04:12:23 -0500, James Sutton wrote:

*** Bug 481096 has been marked as a duplicate of this bug. ***

On 2015-11-12 10:14:00 -0500, James Sutton wrote:

Hi Gnanas,

Thanks for finding this.

The solution that I can see at the moment is that we modify the NetworkModule interface to require a getServerURI method.

This would then mean adding this method to All Classes that implement it (TCPNetworkModule, LocalNetworkModule, SSLNetworkModule, WebSocketNetworkModule & WebSocketSecureNetworkModule).

Then in MqttAsyncClient.getServerURI() we get the current NetworkModule and call getServerURI on it.

In an ideal world, we would model the C API and include it in the onSuccess Callback (in the MQTTToken). However this would mean modifying an interface which could impact other users that build against it. So to avoid causing more trouble, I'll add it to MqttClient and MqttAsyncClient, but not in their interfaces.

On 2015-11-13 06:27:56 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/60307

On 2015-11-13 07:30:53 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/60307 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 2bd10f1

On 2015-11-13 08:07:06 -0500, Gnanaskandan R wrote:

(In reply to James Sutton from comment # 2)

Hi Gnanas,

Thanks for finding this.

The solution that I can see at the moment is that we modify the
NetworkModule interface to require a getServerURI method.

This would then mean adding this method to All Classes that implement it
(TCPNetworkModule, LocalNetworkModule, SSLNetworkModule,
WebSocketNetworkModule & WebSocketSecureNetworkModule).

Then in MqttAsyncClient.getServerURI() we get the current NetworkModule and
call getServerURI on it.

In an ideal world, we would model the C API and include it in the onSuccess
Callback (in the MQTTToken). However this would mean modifying an interface
which could impact other users that build against it. So to avoid causing
more trouble, I'll add it to MqttClient and MqttAsyncClient, but not in
their interfaces.

yeah.. this looks good.. thanks for the prompt fix!

Log message translation in Loggger using ResourceBundle throwing MissingResourceException causes crash

migrated from Bugzilla #471748
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version 1.2 on platform Other
Assigned to: Ian Craggs

On 2015-07-02 17:36:14 -0400, Marc Pomar Torres wrote:

Hi!

I'm using PAHO to do some networking in android, the final goal is to develop a native android Unity Plugin that uses paho as networking client. I've got into a problem regarding the Logger that paho uses in java due to Unity not packing the ResourceBundle that you use to translate log messages with final produced .jar files. I've managed to solve it by simply discarding the translation step by passing a null inside LoggerFactory.getLogger.

Unity supports new android archive library format (.aar file). Is there a way to implement a better Logger in android that uses string translation system provided by android? When ResouceBundle fails i cannot even instance MQTTAsyncClient.

Per subscription callbacks for the Java client APIs

migrated from Bugzilla #466579
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-05-06 08:51:22 -0400, Ian Craggs wrote:

I propose to add per subscription callbacks to the Java client APIs.

For the async client, the subscribe methods

subscribe(String, int)
subscribe(String, int, Object, IMqttActionListener)
subscribe(String[], int[])
subscribe(String[], int[], Object, IMqttActionListener)

would have another 4 added:

subscribe(String, int, IMqttMessageListener)
subscribe(String, int, Object, IMqttActionListener, IMqttMessageListener)
subscribe(String[], int[], IMqttMessageListener)
subscribe(String[], int[], Object, IMqttActionListener, IMqttMessageListener)

where IMqttMessageListener is

public interface IMqttMessageListener {

public void messageArrived(String topic, MqttMessage message) throws Exception;

}

and similarly for the synchronous client.

On 2015-05-06 08:52:54 -0400, Ian Craggs wrote:

Changing assignment and target.

On 2015-06-09 09:46:19 -0400, Ian Craggs wrote:

Code and tests added to the develop branch.

Incoming response does not issue a notify, instead waits for maximum TimeToWait

migrated from Bugzilla #459360
status UNCONFIRMED severity normal in component MQTT-Java for 1.1
Reported in version v0.5 on platform PC
Assigned to: Bin Zhang

On 2015-02-07 08:19:08 -0500, Philipp Gayret wrote:

When publishing messages with org.eclipse.paho.client.mqttv3.MqttClient the client always waits the full TimeToWait, instead of resuming as soon as the acknowledgement comes in.

I'm using org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.1

I believe in the ClientState's notifyResult method the following should be added after the markComplete call on the internal token:

token.internalTok.notifyComplete();

On 2015-08-12 09:09:49 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/53631

On 2015-08-12 09:10:30 -0400, James Sutton wrote:

Implemented this change in Change 53631.

On 2015-08-25 06:19:59 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/53631 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 3236c0a

client.getServerURI() returns wrong URI when servers are configured thru connect options

migrated from Bugzilla #481096
status CLOSED severity normal in component MQTT-Java for 1.2
Reported in version unspecified on platform PC
Assigned to: James Sutton

On 2015-10-30 06:46:12 -0400, Gnanaskandan R wrote:

Hi,

First up, I'd like to thank all the people on the project for the great work! I ran into an issue today and I would like to report it.

I am using ActiveMQ as my MQTT broker. I have set it up with master-slave configuration. Hence, I do this in my Paho client:

String[] servers = {"tcp://localhost:1883","tcp://localhost:1893"};
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(servers);
client.connect(options);

The connect method correctly identifies which URI to use and connects appropriately. However, the MQTTClient mandates a ServerURI in its constructor and that is the URI that is returned when I invoke client.getServerURI(). This is the issue and I am unable to see the actual URI that the client is connected to.

I am sure connection is established because I killed the master broker.

Thanks,
Gnanas.

On 2015-11-06 04:12:23 -0500, James Sutton wrote:

*** This bug has been marked as a duplicate of bug 481097 ***

MQTT connection not closed if WebSocket closed by server

migrated from Bugzilla #482928
status RESOLVED severity normal in component MQTT-Java for 1.2
Reported in version future on platform PC
Assigned to: James Sutton

On 2015-11-24 11:34:32 -0500, Tristam MacDonald wrote:

When the server closes a websocket connection, Paho does not detect that the socket has been closed.

I believe that this is due to the empty catch block here:

http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/tree/org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketReceiver.java?h=develop#n103

And that it can be remedied by calling pipedeOutputStream.close() at that point.

On 2015-11-25 05:39:21 -0500, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/61228

On 2015-11-25 05:39:56 -0500, James Sutton wrote:

Thanks for spotting that Tristam, fix submitted.

On 2015-11-26 16:34:13 -0500, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/61228 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 7212fae

Deadlocked "MQTT Rec:" When "MQTT Call:" Dies

migrated from Bugzilla #443142
status RESOLVED severity blocker in component MQTT-Java for 1.1
Reported in version unspecified on platform All
Assigned to: Bin Zhang

Original attachment names and IDs:

On 2014-09-02 15:56:42 -0400, Gary Russell wrote:

See my analysis here: http://stackoverflow.com/questions/25620196/spring-integration-mqtt-subscriber-paho-stops-processing-messages/25631077# 25631077

When an exception is thrown on the "Call" thread, and the "Rec" thread is blocked because the queue is full, the connection is shutdown but that causes a deadlock because the "Snd" thread waits for the "Rec" thread, which will never exit.

It looks like the 'spaceAvailable.notifyAll()' needs to go into a finally block.

On 2014-09-02 15:57:27 -0400, Gary Russell wrote:

This is with the 0.4.0 client, but it looks the same on master.

On 2014-09-02 17:00:13 -0400, Gary Russell wrote:

I see the same problem in 'CommSender.handleRunException(). If the sender throws an exception, it callsclientComms.shutDownConnection()` which, again waits for the 'Rec:' thread to stop, which will never happen because he is blocked on 'spaceAvailable'.

On 2014-09-15 04:06:59 -0400, Bin Zhang wrote:

Could you please paste the stack trace when using the paho java client code on master?

On 2014-09-17 04:36:11 -0400, Gary Russell wrote:

I won't be able to get to this until at least Sept 25th.

I will see if I can have a colleague help you.

However, it was easy to reproduce a similar deadlock (in the 0.4 released client - I didn't try on master).

Send > 10 messages

In MessageArrived() use

Thread.sleep(1000); // so the Rec: queue is full and the thread suspended
throw SomeException()

The Call: thread is deadlocked waiting to join the Rec: thread.

On 2014-09-17 06:13:59 -0400, Bin Zhang wrote:

Unfortunately, i failed to reproduce the issue according the steps you described if i understand correctly with code on master�

It would be great if your colleague can provide a test to reproduce this issue with code on master, since several deadlock bugs were fixed since 0.4 release.

Thanks.

On 2014-09-17 13:03:24 -0400, Artem Bilan wrote:

Created attachment 247164
Test-case to reproduce

See test-case in the attachment. Reproducable on the 0.4.0 as well as on the 0.4.1-SNAPSHOT.
As Gary said there is need to change this code in the CommsCallback:
synchronized (spaceAvailable) {
// Notify the spaceAvailable lock, to say that there's now
// some space on the queue...

              // @TRACE 706=notify spaceAvailable
              log.fine(CLASS_NAME, methodName, "706");
              spaceAvailable.notifyAll();
          }
      } catch (Throwable ex) {
          // Users code could throw an Error or Exception e.g. in the case
          // of class NoClassDefFoundError
          // @TRACE 714=callback threw exception
          log.fine(CLASS_NAME, methodName, "714", null, ex);
          running = false;
          clientComms.shutdownConnection(null, new MqttException(ex));
      }

when we have to move spaceAvailable.notifyAll(); to finally block.

On 2014-09-18 12:06:11 -0400, Bin Zhang wrote:

Tried moving spaceAvailable.notifyAll(); to finally block, the test still failed.

CommsCallback calls ClientComms.shutdownConnection() once it caught some exception in the callback thread,
and it stops networkModule which closes the socket, and then CommsReceiver will got SocketException and running=false, thread stopped.

Regarding this condition: while (!quiescing && messageQueue.size() >= INBOUND_QUEUE_SIZE) { spaceAvailable.wait(); ... ,
even spaceAvailable.notifyAll() is called, the while condition is still true, it continues waiting.

Actually, i think it's not reasonable an exception thrown from the MqttCallback that causes the MQTT client to shutdown.

Any ideas?

On 2014-09-19 08:48:53 -0400, Artem Bilan wrote:

Eh... Sorry, now I see that my test-case doesn't show the real issue.
It wasn't really clear from Gary's comments.

However I agree that it is very aggressive to stop Client on an Exception from the target application's MqttCallback implementation.

On 2014-09-29 05:18:31 -0400, Gary Russell wrote:

This reproduces a similar deadlock:

https://gist.github.com/garyrussell/80577e9e8eb865aa37f0

Deadlocks with the released (0.4.0) client as well as current GitHub master.

After running the program...

$ ps -ef | grep Deadlock | grep -v grep | awk '{ print $2 }' | xargs jstack

...

"MQTT Call: bar" prio=5 tid=0x00007fedf1879000 nid=0x4c03 in Object.wait() [0x000000011fe2e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)

  • waiting on <0x000000010a1245b8> (a java.lang.Thread)
    at java.lang.Thread.join(Thread.java:1260)
  • locked <0x000000010a1245b8> (a java.lang.Thread)
    at java.lang.Thread.join(Thread.java:1334)
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.stop(CommsReceiver.java:83)
  • locked <0x000000010a1243a8> (a java.lang.Object)
    at org.eclipse.paho.client.mqttv3.internal.ClientComms.shutdownConnection(ClientComms.java:307)
    at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:184)
    at java.lang.Thread.run(Thread.java:724)

"MQTT Rec: bar" prio=5 tid=0x00007fedf288f000 nid=0x4a03 in Object.wait() [0x000000011fc28000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)

  • waiting on <0x000000010a111350> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:503)
    at org.eclipse.paho.client.mqttv3.internal.CommsCallback.messageArrived(CommsCallback.java:299)
  • locked <0x000000010a111350> (a java.lang.Object)
    at org.eclipse.paho.client.mqttv3.internal.ClientState.notifyReceivedMsg(ClientState.java:864)
    at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:127)
    at java.lang.Thread.run(Thread.java:724)
    ...

Note that the Call: thread is waiting to join the Rec: thread, which is waiting on spaceAvailable.

On 2014-09-30 06:37:49 -0400, Bin Zhang wrote:

The root cause is the CommsCallback.messageArrived, the while
condition will never be false when the messageQueue is full and not quiescing, even when the callback thread is trying to stop.

I will fix this.

On 2014-09-30 06:50:43 -0400, Bin Zhang wrote:

Fixed in develop branch via https://git.eclipse.org/r/#/c/34109/

On 2014-10-28 12:22:45 -0400, Gary Russell wrote:

Any plans to release this fix? I only see the old 0.4 release in maven: https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/mqtt-client/

On 2015-05-06 04:17:50 -0400, Anand J. Kadhi wrote:

So if this issue is fixed in which release can we get the fixed version, actually currently we are using spring-integration-mqtt 4.1.3 version which internally uses the mqtt-client 0.4.0, and we are facing the same problem. can you please tell where can i get the jar with the above fix?

On 2015-05-06 04:46:28 -0400, Gary Russell wrote:

The maven artifactId has changed. I just tested Spring Integration against the 1.0.2 release.

Repo: https://repo.eclipse.org/content/repositories/paho-releases/
GroupId: org.eclipse.paho
ArtifactId: org.eclipse.paho.client.mqttv3

On 2015-05-06 06:01:27 -0400, Davy De Waele wrote:

Gary,

If I understand correctly the latest version of Spring Integration still uses the (very) old 0.4.0 paho mqtt client.

Are there plans to align Spring integration with a more recent version of Paho.

I have the impression lots of people are confused / unaware of the maven groupId/artifactId change and most of them are still on 0.4.0

Would it be a good idea to exclude the 0.4.0 and replace it with a more recent 1.0.x release and test it against spring integration 4.1.3 ?

On 2015-05-06 06:12:02 -0400, Gary Russell wrote:

Yes, we have an open JIRA issue 1 to upgrade, but we're having some problems pulling it into the spring.io repository; it's some problem with the parent pom group id and the way our cache is set up. We like to do that so users don't have to worry about adding the eclipse repo to their project.

I ran the test suite this morning with the 1.0.2 artifact. So, yes, until INT-3645 is resolved, I suggest you do as you say (exclude the old artifact and pull in the new one from the eclipse repo).

Please report any issues you find (that are Spring Integration related) using our JIRA.

Thanks

On 2015-05-06 06:14:51 -0400, Ian Craggs wrote:

We tried removing 0.4 from the Nexus repository last year, to stop new implementations using it, and to make people aware of the change in name. That caused an outcry so we had to put it back.

Unfortunately, the package name had to change when the first official Eclipse release was made, to conform to Eclipse naming conventions.

On 2015-05-06 06:22:41 -0400, Davy De Waele wrote:

Hi Ian,

I understand, once released it's not trivial to remove.

But I would like to urge the Eclipse Paho site maintainers to highlight their note on the groupId/artidactId in a larger font and in red :)

On 2015-05-06 06:29:09 -0400, Ian Craggs wrote:

(In reply to Davy De Waele from comment # 18)

Hi Ian,

I understand, once released it's not trivial to remove.

But I would like to urge the Eclipse Paho site maintainers to highlight
their note on the groupId/artidactId in a larger font and in red :)

Should I make it blink as well?

On 2015-05-06 06:52:58 -0400, Ian Craggs wrote:

I've moved the message, to make it more prominent, added version numbers, and turned it red. But I haven't made it blink :-)

On 2015-05-06 07:44:40 -0400, Davy De Waele wrote:

No worries, I'll log another issue to make it blink :)

On 2015-05-07 01:31:32 -0400, Anand J. Kadhi wrote:

Hi team,
Thanks for the help i have replaced the maven groupId and artifactId now it's working fine. Great.

Paho prevents the default Java SSL session resumption

migrated from Bugzilla #469947
status ASSIGNED severity normal in component MQTT-Java for 1.2
Reported in version 1.0 on platform PC
Assigned to: James Sutton

Original attachment names and IDs:

On 2015-06-11 09:56:54 -0400, Cristiano De Alti wrote:

Created attachment 254336
Patch, test case, logs and captures

When re-connecting to the same server and port using SSL, Paho prevents the default Java SSL session resumption mechanism, i.e. an abbreviated SSL handshake for subsequent connections.

Being able to resume the old SSL session is particularly important for slow (GPRS) connections with limited network traffic (some MBi/month).

The issue is related to how Paho needs to stop the receiver thread and how it reads the socket input stream.

Paho uses a blocking read of the socket input stream with a very long (infinite?) socket timeout.

Due to this, in order to stop the receiver thread it has to forcibly close the socket while the thread is blocked on the read.

This causes the read to throw a SocketException which has the effect to also invalidate the SSL session.

Since the session has been invalidated, the next connection will perform a full SSL handshake wasting precious GPRS traffic.

Please see the attachment for the proposed patch, test case, SSL debug logs and Wireshark captures.

Please note that the proposed fix, despite it's just a single line change and should not cause any harm, might work only on some JVMs/OSs (we use Oracle Java SE 7 on Linux OS).

The right fix would imply rewriting how Paho reads the input stream using short socket timeouts.

On 2015-06-11 10:11:43 -0400, Ian Craggs wrote:

Hi. The attachment doesn't look right. Is it supposed to be a zip file?

On 2015-06-11 10:21:58 -0400, Cristiano De Alti wrote:

Comment on attachment 254336
Patch, test case, logs and captures

Removed

On 2015-06-11 10:23:47 -0400, Cristiano De Alti wrote:

Created attachment 254338
Patch, test case, logs and captures

On 2015-06-12 06:46:38 -0400, Cristiano De Alti wrote:

Sorry,
The proposed patch does not work.
The call to shutdownInput() actually throws an UnsupportedOperationException since is not supported by an SSLSocket.

The exception is actually caught by a block which ignores it.

Please ignore the proposed patch in the attachment.

The analysis is OK though.

On 2015-06-16 11:47:55 -0400, Cristiano De Alti wrote:

Created attachment 254479
Implement socket read timeout

Hi,

This patch tries to fix the issue by implementing a 1 second socket read timeout.
This allows the receiver thread to check if it is asked to exit and allows to avoid closing the socket while the thread is reading from the socket input stream.

It looks ok to me (all tests pass).

The 1 second timeout might be questionable since it causes the read to throw a SocketTimeoutException every second.
It is now hardcoded in the TCPNetworkModule but must be known by CommsReceiver (see WARNING comment).

The timeout should be probably configurable by the application.

On 2015-06-22 05:53:14 -0400, Ian Craggs wrote:

I've been talking to one of our Java experts who doesn't think that the closing of the socket in the way that the Paho client does it is the cause of the SSL session not being able to be resumed.

I haven't found any documentation about SSL session resumption in Java, yet. Do you know of any?

The introduction of the socket read timeout does introduce a variable which I'm uncomfortable about adding unless we're sure this is the best or only approach.

On 2015-06-22 09:55:48 -0400, Cristiano De Alti wrote:

Hi,
Thanks for the feedback.

I've been talking to one of our Java experts who doesn't think that the closing of the socket in the way that the Paho client does it is the cause of the SSL session not being able to be resumed.

The Java SSL log (obtained with -Djavax.net.debug=all) is in the original attachment.

This also includes the Wireshark captures.

You should be able to recreate the issue with the provided test case (in the attachment), at least on Linux and the Oracle Java SE 7u45 64 bit.

I haven't found any documentation about SSL session resumption in Java, yet. Do you know of any?

Unfortunately I don't. Experimentally I observed that every time the socket is closed while a read is in progress, a SocketException is thrown (documented in the Javadoc) and the session is invalidated (see attached logs).

The introduction of the socket read timeout does introduce a variable which I'm uncomfortable about adding unless we're sure this is the best or only approach.

I agree. Unfortunately I could not find any other method and the patched version seems to work fine so far.

No need to say that the abbreviated SSL hadshake allows to save some kBi that on a GPRS link with 1MBi/month of traffic is not negligible (on a GPRS link connection losses can occur quite often).

Please try the test case on the original and patched version and see the difference with Wireshark.

Regards,
Cristiano

On 2015-08-06 10:29:30 -0400, Cristiano De Alti wrote:

Created attachment 255674
Always modify the socket read timeout during the SSL handshake

After enabling the socket read timeout, on slow cellular links, the SSL connection handshake timeouts due to the following code of org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule:

if ( soTimeout == 0 ) {
// RTC 765: Set a timeout to avoid the SSL handshake being blocked indefinitely
socket.setSoTimeout(this.handshakeTimeoutSecs*1000);
}

As the comment suggests, the code was intended to timeout the SSL handshake when the default socket timeout (soTimeout) was 0 (infinite).

Since my patch sets a 1 second socket read timeout, the above condition is false and the SSL connection handshake will timeout on slow links.

This new patch supersedes the old one by skipping the above check for soTimeout and always modifies the timeout during the SSL handshake.

The patch is cumulative and includes the previous patch "254479: Implement socket read timeout" plus what described here.

On 2015-08-31 16:42:54 -0400, Ian Craggs wrote:

Thanks Cristiano, for all your work on this one. I'd like to think there is a different, perhaps better, solution to the having a one second timeout on the read, and am going to ask on the mailing list to see if there are any other suggestions or advice.

On 2015-10-02 10:03:37 -0400, Cristiano De Alti wrote:

Hello,
This patch has been in production for the last two releases of our ESF framework.
It seems to work fine.
Note that some of our gateways are connected over GPRS cellular links often with unstable connectivity.
What about submitting the patch as a pull request to the Paho github repository for others to review it?

Regards,
Cristiano

On 2015-10-15 14:17:57 -0400, Benjamin Cabé wrote:

(In reply to Cristiano De Alti from comment # 10)

What about submitting the patch as a pull request to the Paho github
repository for others to review it?

That sounds like a very reasonable approach :) Cristiano, are you familiar with how Gerrit works for submitting your PR?

On 2015-10-16 06:23:16 -0400, Ian Craggs wrote:

I think that's reasonable too.

Even though I'm still somewhat uncomfortable about making this change, I've not found any alternative suggestion that works so far. I guess if we make the change and try it out in our tests, then we'll get some idea of whether it's going to cause any problems for existing applications.

I'm going to assign this to James to implement.

Cristiano, could you please sign the Eclipse CLA?
https://eclipse.org/legal/CLA.php

Additionally, a contributing guide is here:
http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/about/
but I'm thinking we can take the patch, if you sign the CLA.

Thanks!

On 2015-10-16 10:19:23 -0400, Cristiano De Alti wrote:

Thanks,
I've signed the CLA.
Does this mean I don't need to submit the PR through Gerrit and the attached patch will do?

Regards,
Cristiano

Client sends PubComp after disconnect.

migrated from Bugzilla #468334
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-05-26 10:34:38 -0400, Andrew Banks wrote:

A client application executes:

Connect,
Subscribe,
Publish Qos=2,
Receives the published message.
Disconnect.

The server returns the publication without waiting for the client PubRel, as it is allowed to do.

Occasionally the client sends PubComp for the message it has received, after the final disconnect packet.

Sequence of packets observed in the server.

3 Mon May 18 22:58:07 BST 2015 SEND_MQTT mqttMessageType:SUBACK
4 Mon May 18 22:58:07 BST 2015 RECEIVED_MQTT mqttMessageType:PUBLISH
5 Mon May 18 22:58:07 BST 2015 SEND_MQTT mqttMessageType:PUBREC
6 Mon May 18 22:58:07 BST 2015 SEND_MQTT mqttMessageType:PUBLISH
7 Mon May 18 22:58:07 BST 2015 RECEIVED_MQTT mqttMessageType:PUBREL
8 Mon May 18 22:58:07 BST 2015 SEND_MQTT mqttMessageType:PUBCOMP
9 Mon May 18 22:58:07 BST 2015 RECEIVED_MQTT mqttMessageType:PUBREC
0 Mon May 18 22:58:07 BST 2015 SEND_MQTT mqttMessageType:PUBREL
1 Mon May 18 22:58:07 BST 2015 RECEIVED_MQTT mqttMessageType:DISCONNECT
2 Mon May 18 22:58:07 BST 2015 RECEIVED_MQTT mqttMessageType:PUBCOMP
113 historyIndex=3(int)

SEND_MQTT means sent by the server,
RECEIVED_MQTT means received by the server.

On 2015-06-05 05:53:41 -0400, Ian Craggs wrote:

Andy, is there a specific test program which exhibits this problem?

On 2015-06-08 05:26:11 -0400, Andrew Banks wrote:

Ian, we've seen this from a number of tests, all of them run multiple clients in the same JVM. I've sent you some examples separately.

Message over MQTT received twice and three times if its payload exceeds around 200MB

migrated from Bugzilla #436784
status RESOLVED severity normal in component MQTT-Java for 0.9
Reported in version 1.0 on platform Macintosh
Assigned to: Bin Zhang

On 2014-06-06 04:59:29 -0400, H. A. Samad wrote:

The client somehow happens to receive a message more than one time, if its payload exceeds 200MB (this is not an exact figure, since I tested by gradually increasing the payload by 5MB message by message).

My broker is Mosquitto. I tried all QOS configurations, Still the same.

Remarkably, this does not happen when working with the Paho Python library, using the same setup. So my environment (network, broker, publishing client, etc.) should be fine.

On 2014-06-09 04:21:18 -0400, Benjamin Cabé wrote:

You may want to share progress with this guy on SO :) http://stackoverflow.com/questions/24077682/message-over-mqtt-received-twice-and-three-times-if-its-payload-exceeds-200mb

On 2014-06-09 04:24:38 -0400, H. A. Samad wrote:

(In reply to Benjamin Cabé from comment # 1)

You may want to share progress with this guy on SO :)
http://stackoverflow.com/questions/24077682/message-over-mqtt-received-twice-
and-three-times-if-its-payload-exceeds-200mb

That's my question already ;)

On 2014-06-09 04:29:48 -0400, Benjamin Cabé wrote:

Ah lol. Sorry :) I misread and thought Al did report the bug!

On 2014-06-16 11:45:44 -0400, Bin Zhang wrote:

What's your paho client version, and any test case to reproduce this issue?

On 2014-07-09 11:46:17 -0400, H. A. Samad wrote:

Paho 1.0
I tried several code snippets from the internet, which all are nothing but a "hello world" Paho examples... So pretty simple stuff.

On 2014-08-20 05:01:09 -0400, Bin Zhang wrote:

I cannot reproduce this issue.

Tried many cases with paho 1.0 & latest version with mosquitto version 1.3.1

  1. message size <200MB, =200MB and >200MB and QoS=0,1,2
  2. client1 sub and client2 pub.
  3. client1 sub and pub.
    All cannot reproduce the issue(the message was received exactly once).

Please provide a reproducible test code if you are still seeing the issue.

On 2015-12-30 01:49:59 -0500, Jayanth Nanjundaiah wrote:

Hi,

I have faced similar kind of issue but in a different way.

Step 1 : Connected to mqtt broker and subscribes to a topic.

Step 2 : If there is a message received from the topic, the message will be received once.

Step 3 : When it gets disconnected and is connected again. If a message is received it will be received twice(I guess since it is the second time it is getting connected).

Step 4: Step 3 : When it gets disconnected again and is connected again. If a message is received it will be received thrice(I guess since it is the third time it is getting connected).

Step 5 : The continues as many times the connection is broken and connected.

Please help me out with this one.

Supporting different passwords for the keystore and the key stored in the keystore

migrated from Bugzilla #468453
status UNCONFIRMED severity normal in component MQTT-Java for 1.2
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2015-05-27 05:41:48 -0400, Davy De Waele wrote:

AFAIK, there is currently no support for an SSL based setup where the password of the key stored in the keystore is different from the keystore password itself.

We can pass the following properties, but there is no way to specify a keyStoreKeyPassword.

-D2javax.net.ssl.keyStore
-D2javax.net.ssl.keyStorePassword
-D2javax.net.ssl.trustStore
-D2javax.net.ssl.trustStorePassword

AFAIK the only way to pass a key password is to create your own KeyManager.

Would be nice if there would be some kind of support in Paho for this.

Can this be made to work over WebSockets?

Hi, I'm currently using this library in an app and thanks for all the hard work.

We were thinking of moving all our backend communication to ports 80/443 (since enterprise environments usually only allow those outgoing ports) but unfortunately this library does not use WebSockets so it doesn't look possible currently.

It would be nice if this client provided MQTT over WebSockets with an option.

Message Not arrived after reconnect to broker with same client id and clean session false.I am using eclipse paho java mqtt client 0.4.0

migrated from Bugzilla #480715
status RESOLVED severity critical in component MQTT-Java for 1.2
Reported in version v0.5 on platform PC
Assigned to: James Sutton

Original attachment names and IDs:

On 2015-10-27 01:49:00 -0400, Avnish Yadav wrote:

Created attachment 257530
Complete src code

1)Connect subscriber client with qos2 and clean session false and subscribe the topic.say "topic" I have set call back as mqtt listener.
2)Publish message with qos2 and topic say "topic"
3)Subscriber client received the message and messageArrived called successfully
4)Restart the broker
5)Subscriber client listener connectionLost() will be called and tried to reconnect the same client with broker with clean session false.Client connected successfully.
6)when I publish message to same topic but subscriber client is not able to receives the message after reconnect.
Please find the attached complete src code.

On 2015-11-09 06:08:35 -0500, James Sutton wrote:

Hi Avnish,

I've tried your source code with my locally running mosquitto broker and this works for me.
To test this I published using: "mosquitto_pub -h localhost -p 1883 -t test -m "Hello World" -q 2" and restarted the broker half way through. Logs shown below.

Subscriber Connected SUCCESS.....
Topic subscrbed!!!!
BrokerListener:messageArrived start{}
BrokerListener:messageArrived start{}
BrokerListener:messageArrived start{}
ConnectionLost: clientId=SUF65xafgaFkjsddf13 serverURL=tcp://localhost:1883 cause=java.io.EOFException
REConnect Successfully************************
BrokerListener:messageArrived start{}
BrokerListener:messageArrived start{}

Could this be an issue with the broker you are using?

On 2015-11-09 08:53:07 -0500, Avnish Yadav wrote:

Yes I found the issue.I was using mosquitto older version.When I installed latest version issue got resolved.Thanks for reply.

On 2015-11-09 09:00:03 -0500, James Sutton wrote:

Thanks Avnish, glad it worked out. Closing bug as invalid as caused by an old version of Mosquitto.

New Feature Plan: Automatic Reconnect and Disconnected Buffering

Automatic Reconnect and Disconnected Publishing Plan

Currently, the Paho Java client is lacking two major areas of functionality: Automatic Reconnect and Disconnected (or Offline) Publishing.
The goal is to implement these features in time for the next release Neon.

This issue aims to outline the plan for adding this new functionality into the client and has been modeled off Mike Tran's plan and work for the same functionality in the Javascript Client.

Recap: Possible Client States

There are 5 main potential states that the client can be in. The User will usually desire the client to either be in the connected or disconnected states.

  • never connected: This is the initial state of the client where:
    • The client has not yet sent a connect request.
    • The client has never received a CONNACK after it's initial connect request.
  • connecting: A connect request is in progress.
  • connected: The client is connected and ready to send and receive messages.
  • disconnecting: A disconnect request is in progress.
  • disconnected: The client goes from connected to disconnected state when:
    • A disconnect request has been completed
    • As a result of a networking error, or the server is no longer reachable.

What does it do?

Automatic Reconnect

Will automatically attempt to reconnect to the broker (or one of the servers in the host list) while the client is in disconnected state.

  • The client will not perform automatic reconnection if it is not in disconnected state.
  • When the connection is list, the connectionLost() callback is called before the client starts the reconnect process. Since the state of the client is disconnected, the application is allowed to call the connect function with new connection options if they wish.
  • When disconnect is called while connected, the client goes to the disconnected state and automatic reconnect is disabled.
  • If the client application calls connect after it had reconnected, an invalid state error will be thrown.
  • The client library does not subscribe for the application after it successfully reconnects. A callback will be provided to notify the application when it has been reconnected allowing it to make any subscriptions to topics itself.

Disconnected Publishing

Will allow the client to save messages in a buffer whilst the client is in the disconnected state.

  • Once the client is reconnected (To the same or different broker), the buffered messages are scheduled to be sent.
  • To maintain order of messages, the client library must send buffered messages before sending new messages.
  • The client library does not save any messages while the client is in the never connected state. So it cannot send any messages before it connects for the first time.
  • When disconnect is called while connected, the client goes to disconnected state and Disconnected Publishing remains active if enabled.

API Changes

Automatic Reconnect

  • The following optional attributes will be added to the MqttConnectOptions class:
    • setReconnect(boolean reconnect) : If true, the client will attempt to reconnect when the connection is lost. Default: False
  • A new interface called MqttCallbackExtended will be created which will extend MqttCallback modifying / adding a few methods. This will be set in the existing setCallback method in the client:
    • Addition of a new callback connectionComplete(boolean reconnect, String serverUri). This would not replace the existing IMqttToken that you get if you call connectWithResult (So that we don't break any functionality). However it would serve the same purpose, it would be called every time that the client connects or reconnects to the broker. This will allow the application to re-make any subscriptions that were lost or to send any held messages if it is not using Disconnected Publishing.
      The boolean reconnect attribute is set to true if the connection was the result of an automatic reconnection, else it is false. The String serverUri attribute contains the URI of the server that the connection was re-made to, this is useful in scenarios where multiple server URIs are provided to the MqttConnectOptions.
  • The method reconnect() will be added to the MqttAsyncClient class, this will make the client attempt to reconnect straight away if in the middle of a retry interval. I'm thinking about reseting the retry interval if this is ever called with the assumption that the user knows what they're doing.
  • If the cleanSession flag is false, then any subscriptions would not have to be re-made
  • Once the client has been disconnected, the client will attempt to connect with an increasing time interval. Starting at 1 second, doubling on each failed attempt up to 2 minutes. This prevents both waiting an unnecessary amount of time between reconnect attempts, and also from wasting bandwidth from attempting to connect too frequently.

Disconnected Publising

  • To maintain the order of the messages, the client must ensure that buffered messages are scheduled to be sent before new messages.
  • A new optional class called DisconnectedBufferOptions will be created with the following attributes & relevant getters and setters:
    • disconnectedPublishing: If true, the client will store messages whilst disconnected. Default: False
    • disconnectedBufferSize: The maximum number of messages that will be stored in memory while the client is disconnected. Default: 5000
    • persistDisconnectedBuffer: If true, the client will persist the messages to disk, if false or not present, the messages will only be saved in memory. Default: False
    • deleteOldestBufferedMessages:If true, the client will delete the 0th message in the buffer once it is full and a new message is published. Default: False
  • The following optional methods will be added to the MqttAsyncClient class:
    • void setDisconnectedBufferOptions: Sets the DisconnectedBufferOptions before a connect.
    • int getBufferedMessagesCount : Returns the number of messages in the buffer.
    • MqttMessage getBufferedMessage(int index): Returns the MqttMessage at the index location.
    • void deleteBufferedMessage(int index) : Deletes the buffered message at the index location.

The following change will be made to the MqttAsyncClient class:

  • publish : Currently throws an MqttException. If the buffer is full, this will be thrown containing a message explaining that the Message buffer is full.

Sample application

Example 1

This application wants to use both Automatic Reconnect and Disconnected Publishing. The Application does not want to persist buffered messages.

public static void main( String[] args )
    {

        String topic        = "/greenhouse/temperature";
        String broker       = "tcp://iot.eclipse.org:1883";
        String clientId     = "TemperatureMonitor_42";
        MemoryPersistence persistence = new MemoryPersistence();

        try {
            MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);

            sampleClient.setCallback(new MqttCallbackExtended() {

                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    // Not used
                }

                public void deliveryComplete(IMqttDeliveryToken token) {
                    // Not used
                }

                public void connectionLost(Throwable cause) {
                    System.out.println("Connection Lost: " + cause.getMessage());
                }

                public void connectionComplete(boolean reconnect) {
                    // Make or re-make subscriptions here
                    if(reconnect){
                        System.out.println("Automatically Reconnected to Broker!");
                    } else {
                        System.out.println("Connected To Broker for the first time!");
                    }
                }
            });


            sampleClient.setReconnect(true);  // Enable Automatic Reconnect

            DisconnectedBufferOptions bufferOpts = new DisconnectedBufferOptions();
            bufferOpts.setDisconnectedPublishing(true); // Enable Disconnected Publishing
            bufferOpts.setDisconnectedBufferSize(100);  // Only Store 1000 messages in the buffer
            bufferOpts.setPersistDisconnectedBuffer(false);  // Do not persist the buffer
            bufferOpts.deleteOldestBufferedMessages(true); // Delete oldest messages once the buffer is full

            sampleClient.setDisconnectedBufferOptions(bufferOpts);

            System.out.println("Connecting to broker: "+broker);
            sampleClient.connect(connOpts);
            System.out.println("Connected");


            /*
             * Sample code to continually publish messages
             */
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {

                @Override
                public void run() {
                    // Publish the current Temperature
                    String temp = String.format("%.2f", getTemperature());
                    System.out.format("Publising temperature %s to topic %s. ", temp, topic);
                    MqttMessage message = new MqttMessage(temp.getBytes());
                    message.setQos(0);
                    try {
                        sampleClient.publish(topic, message);
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }
            }, 5000, 5000);  // Every 5 seconds



        } catch(MqttException me) {
            System.out.println("reason "+me.getReasonCode());
            System.out.println("msg "+me.getMessage());
            System.out.println("loc "+me.getLocalizedMessage());
            System.out.println("cause "+me.getCause());
            System.out.println("excep "+me);
            me.printStackTrace();
        }
    }

Before I start work on this, I'd be very interested in hearing back from the community. Because of the very nature of the features that need to be implemented, it means adding a lot to the API which would mean a small amount of work for developers upgrading their application to use Neon (For example the addition of a callback to MqttCallback). If anyone can spot anything that might cause issues down the line, or thinks that there might be a better way of accomplishing this functionality please do comment!

No way to set maxInflight

migrated from Bugzilla #456855
status RESOLVED severity normal in component MQTT-Java for 1.1
Reported in version unspecified on platform PC
Assigned to: Bin Zhang

On 2015-01-07 01:09:28 -0500, Bin Zhang wrote:

There is no way to set maxInflight (which defaults to 10). MQTT client can easily reach 10 messages/second in a high traffic environment, and as a result an MqttException will be thrown with reason code REASON_CODE_MAX_INFLIGHT.

It's reasonable to increase the maxInflight in this case.

On 2015-01-12 02:18:39 -0500, Bin Zhang wrote:

Fixed in https://git.eclipse.org/r/#/c/39091/

On 2015-02-03 12:01:37 -0500, Bin Zhang wrote:

Resolved as FIXED per my previous comment.

Hi Ian, please review and merge.

On 2015-02-06 06:32:14 -0500, Eclipse Genie wrote:

Gerrit change merged: https://git.eclipse.org/r/39091 was merged.
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 6440239

On 2015-04-28 06:38:01 -0400, Mattias Isegran Bergander wrote:

Was this supposed to be part of the java client lib 1.0.2 (version 1.1)? It was merged 30min before the merge of develop to master if I read the time stamps correctly (but that merge does not contain this) so this fix is NOT part of of that release.

For example, compare MqttConnectOptions.java in develop vs master:

http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/tree/org.eclipse.paho.client.mqttv3/src/main/java/org/eclipse/paho/client/mqttv3/MqttConnectOptions.java

Meaning this commit merge "Merge branch 'develop'":
http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 3f81520

on Feb 6 at 7:01 EST
did not contain this bug report's commit to develop at Feb 6 6:31 EST both by Ian.
http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/commit/?id=SHA: 3f81520

On 2015-08-03 04:51:43 -0400, ridwan nizam wrote:

I am using the latest client version which is 1.0.2, our environment has a high traffic and we are publishing more than 10 messages at the same time. Currently we are suffering from the exception REASON_CODE_MAX_INFLIGHT. We did not have the issue in the older version.

Are you planning to have a new build to include this fix?

Thanks.

The Paho Java client does not perform peer verification on the connected socket

migrated from Bugzilla #425195
status REOPENED severity enhancement in component MQTT-Java for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2014-01-09 09:26:26 -0500, Ian Craggs wrote:

Reported by: [email protected]

The Paho Java client does not perform peer verification on the connected socket. This allows peer spoofing / MITM attacks.

Proposed Solution # 1

Like HttpsURLConnection, the IMQTTClient interface could get something like the following:

void setHostnameVerifier(HostnameVerifier hv);

where Java5 built-in HostNameVerifier interface is either reused as-is or inspires a Paho equivalent.

http://docs.oracle.com/javase/1.5.0/docs/api/javax/net/ssl/HostnameVerifier.html

Proposed Solution # 2
Instead of SSLNetworkModule / TCPNetworkModule creating a disconnected socket via

SocketFactory.createSocket(), use SocketFactory.createSocket(String hostname, int port)

A custom SSLFactory implementation could look like:

class MySSLSocketFactory {

SSLSocketFactory delegate;

SSLSocket createSocket(String hostname, int port) throws IOException {
    SSLSocket s = delegate.createSocket(hostname, port);
    s.startHandshake();
    verifyHostName(s, host);
}

void verifyHostName(Socket s, String host) {
    // Throw exception if fail verification
}

}

In any case, I think the Paho client should not create a disconnected socket; this allows the SSLSocketFactory to apply alternative settings and policies on the created socket.

Note: Java 7 has X509ExtendedTrustManager which is a connection-sensitive trust manager. This may also be leveraged in the future, but is relatively new.

On 2014-01-09 09:36:26 -0500, Ian Craggs wrote:

Al disagrees on the seriousness of this bug report, don't you Al? (And whether it is truly a vulnerability)

On 2014-01-09 09:49:18 -0500, Al Stockdill-Mander wrote:

I do :) In that it depends on your use case, If you're deploying an app that will talk to known servers over SSL you will preseed your trust store with only the certificates relevant to the systems you wish to connect to and the lack of hostname verification doesn't seem to be a problem.

That's not to say I think we shouldn't make this an option anyway.

On 2014-04-22 10:50:27 -0400, Ian Craggs wrote:

So, this is a worthwhile enhancement, but not a vulnerability.

On 2014-05-01 10:03:19 -0400, Al Stockdill-Mander wrote:

what's the vulnerability? You have to steal the private key first to do anything with it.
once you've done that you can already decrypt the communications
i need to review it again. but if a mitm is possible (and i'm not hallucinating) it seems very serious to me. this in conjunction with the likely scenario that mqtt will often be used in IoT scenario, where updating clients may be difficult because they are in remote locations or the sheer number of them
you can't mitm just because we don't do cn checking
you'd have to redirect the client and have stolen a private key that the client would verify
these devices are not going to be webservers/clients. I would very much not recommend putting the whole swathe of root CA certs on them
13:15 < alsm> these devices are not going to be webservers/clients. I would very much not recommend putting the whole swathe of root CA certs on them
This is a point worth repeating.
OK, sounds good, i'm getting rusty at this topic already, its so tricky
if its been reviewed, thats good
But it will be added to the client

Once the J2ME codebase is split off into its own repository we can utilise language features > 1.4.2 and implement the HostNameVerifier interface.

On 2014-11-10 07:14:52 -0500, Davy De Waele wrote:

I noticed this is marked for v0.5 but according to https://projects.eclipse.org/projects/technology.paho/releases/1.1.0/bugs the next release will be v1.1.0

Will this be fixed or will there be a workaround so we are able to do hostname verification ?

On 2015-02-02 11:52:01 -0500, Ian Craggs wrote:

Reassigning to Bin.

On 2015-07-09 07:29:17 -0400, Ian Craggs wrote:

Reassiging back to me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.