User has nickname in room, but not a role
This exception got logged.
The corresponding code attempts to guarantee that fields `occupantsByNickname` and `occupantsByFullJID` (and `occupantsByBareJID`) are always in the same state for a particular user (they either all have a mapping for a user, or they all do not.
The occurrence of the exception below seems to prove that this is not the case. The execution flow shows that 'alreadyJoinedWithThisNick()` returns `true` (indicating that the user is present in the `occupantsByNickname` field), while the NullPointer indicates that the user is not in `occupantsByFullJID`
Community member CHP has looked into this issue, and has found that this occurs when there’s MUC interaction on a cluster node that has not yet finished joining the cluster. An outtake of his comment, including a reference to a suggested fix, on https://discourse.igniterealtime.org/t/null-pointer-exception-joining-a-room/88995/24:
If a cluster node starts, then it can happen that a client establishes a connection and joins the muc before the cluster connection is ready (e.g.: by a plugin, which needs very long time to start).
If the cluster connection is ready, then the senior member queries all the mucs including the online users of the mucs from this cluster node. The cluster node then queries the Mucs including the online users of the cluster from the senior node and enters them in its own maps. However, the cluster node receives its online users again as a RemoteMucRole and overwrites its own LocalMucRole. The consequence is that the user can still send messages, but no longer receive them.
The pull request:
I think it would be better to make the value of the map occupantsByFullJID as a list to avoid such concurrency problems. Methods like getOccupantByFullJID should then return the corresponding “newer” role.
What do you think?