Bug report: NullPointerException at Roster.java:1648

Don’t know how to reproduce.

Smack version: 4.3.1

Exception:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List org.jivesoftware.smack.roster.rosterstore.RosterStore.a()' on a null object reference
       at org.jivesoftware.smack.roster.Roster$RosterResultListener.onSuccess(SourceFile:1648)
       at org.jivesoftware.smack.roster.Roster$RosterResultListener.onSuccess(SourceFile:1596)
       at org.jivesoftware.smack.SmackFuture$1.run(SourceFile:151)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
       at java.lang.Thread.run(Thread.java:764)

mapping:

org.jivesoftware.smack.roster.rosterstore.RosterStore -> org.jivesoftware.smack.roster.rosterstore.RosterStore:
    java.util.List getEntries() -> a

Thanks for reporting this. :slight_smile:

One possible way to trigger this is if the RosterStore is set to null while a versioned roster is retrieved. While it is not really someone should ever do, it is trivial to make Smack more robust against this.

Adding info from the 2 crash reports I’ve got:

Both reports include threads having this entry: org.jivesoftware.smack.tcp.XMPPTCPConnection.notifyConnectionError.
I don’t know much of Smack’s internals but, given the correlation, the cause of this crash may be related to a possible racing condition when a Roster response is being consumed just after the connection having been dropped.

I noticed one suspicious thing: my IDE can’t find any usage of the Roster#setRosterStore setter method from either my application of any other library in my dependency graph, suggesting this field is always null. I don’t initialize or even use Roster directly. I do use ChatManager though, which seems to use it.

Confirming: by adding a breakpoint to RosterResultListener#onSuccess, I can see the #rosterStore field is always null after a reload triggered by a connect+login.

stanza ids are unique per connection, right?

I can’t find in AbstractXMPPConnection any code that clears its #syncRecvListeners and #asyncRecvListeners maps upon disconnections. If they’re really not cleared, a mismatched stanza may be delivered to a wrong listener that didn’t timeout yet after disconnecting and connecting the same AbstractXMPPConnection instance.

That would explain why RosterResultListener#onSuccess is getting a stanza that’s not a RosterPackage when it supposedly didn’t make any versioned request (as per Roster#reload's implementation when rosterStore is null)

@Flow mentioning you because you’ve been active in other threads and may have missed new messages in this thread.

This topic was automatically closed 62 days after the last reply. New replies are no longer allowed.