"Exception reloading roster" and related problems

If I use several XMPP connections at the same time, I often meet following problem.

Sometimes one or more account get “Exception reloading roster” and it breakes this connection.

I did not dive in deeply so far, but for now I have:

2017-01-27_18-50-55 D/Smack﹕ SENT (3):

2017-01-27_18-50-55 D/Smack﹕ RECV (3):

… 30 seconds pass …

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ Exception reloading roster

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 30000ms (~30s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=3ovju-2492)), : fromFilter (OrFilter: (FromMatchesFilter (full): null, FromMatchesFilter (ignoreResourcepart): grigory.fedorov@creep.im, FromMatchesFilter (full): creep.im)).

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ org.jivesoftware.smack.AbstractXMPPConnection$7.run(AbstractXMPPConnection.java :1523)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.util.concurrent.FutureTask.run(FutureTask.java:237)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Schedu ledThreadPoolExecutor.java:272)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)

2017-01-27_18-51-25 E/org.jivesoftware.smack.roster.Roster﹕ java.lang.Thread.run(Thread.java:761)

For some reasons roster stanza does not parsed correctly.

In next reconnection (caused by network changing)

only “ConnectionListener.connected()” is called, “authenticated” does not called nether again. But “User logged (3)” successfully. Roster in not requested after reconnection.

setRosterLoadedAtLogin is set to true.

So, for some reasons “Exception reloading roster” hangs connection between “connected” and “authenticated” states. Also it look strange to have such exception if roster stanza was received correctly.

I think I never meet such problem using one connection.

I will try to look into the code of XMPPTCPConnection to better understand the problem (not sure if I can understand it though)

That is indeed very strange. As you can see, the used IQReplyFilter should match the Roster result stanza. Also that you say that you only see that in case when multiple connections are active.

So, for some reasons “Exception reloading roster” hangs connection between “connected” and “authenticated” states
That, at least is perfectly normal, as the reloading is done synchronous. But the NoResponseException should not happen in the first place.

For now I have the feeling that finally block in Smack/AbstractXMPPConnection.java at f2a3cce0941cfb1e34958a0001b0b4f95948f8c9 · igniterealtime/Smack · GitHub does not executed due to thread killed or something. May be because of high load - I try to request last history from MAM for every contact.

So I’m going to recover from roster load exception first and think about threading second.

For now I have the feeling that finally block in Smack/AbstractXMPPConnection.java at f2a3cce0941cfb1e34958a0001b0b4f95948f8c9 · igniterealtime/Smack · GitHub does not executed due to thread killed or something. May be because of high load - I try to request last history from MAM for every contact.

Hmm, I’m not sure why i’ve put the removeAsyncStanzaListener into the finally block. If callback.processStanza(Stanza) takes a long time (or even blocks), then it would appear to the “no response” handling Runnable as if there was no response, when in fact, there was one.

I’ve uploaded a new version of 4.2.0-rc3-SNAPSHOT with sendStanzaWithResponseCallback(): remove listener right away · Flowdalic/Smack@d62255e · GitHub . As always, please try and report back.

Thanks! I do not see this exception anymore.

But now it seems that Roster#getEntries() is sometimes blocked. Is it possible?

I call it inside RosterListener#entriesAdded.

But now it seems that Roster#getEntries() is sometimes blocked. Is it possible?

Not that I can see.

private void fireRosterChangedEvent(final Collection addedEntries, final Collection updatedEntries,

final Collection deletedEntries) {

synchronized (rosterListenersAndEntriesLock) {

for (RosterListener listener : rosterListeners) {

if (!addedEntries.isEmpty()) {

listener.entriesAdded(addedEntries);

}

if (!updatedEntries.isEmpty()) {

listener.entriesUpdated(updatedEntries);

}

if (!deletedEntries.isEmpty()) {

listener.entriesDeleted(deletedEntries);

}

}

}

}

public Set getEntries() {

Set allEntries;

synchronized (rosterListenersAndEntriesLock) {

allEntries = new HashSet<>(entries.size());

for (RosterEntry entry : entries.values()) {

allEntries.add(entry);

}

}

return allEntries;

}

Both take the same lock, thus calling getEntires() in entriesAdded() is perfectly safe.