powered by Jive Software

NullPointerException in ChatManager (Smack 3.4.1)

Hi all,

I’m using Smack to interface with a hardware device that runs an XMPP server. It occasionally sends out elements that look like this:

The message has no from, to, or thread attributes. I suspect this is somewhat unusual (the XMPP server in this device could be weird), but reading through RFC-3921, I couldn’t find anything explicitly forbidding a message with no thread/from/to attributes.Unfortunately, it causes a NullPointerException in ChatManager.

When the processPacket(Packet) method from the anonymous PacketListener is invoked with this empty message element, it can’t find a thread-ID (because there isn’t one). It then calls getUserChat(message.getFrom()), but there’s no From attribute either. Last, it tries to call createChat:

public void processPacket(Packet packet) {

Message message = (Message) packet;

Chat chat;

if (message.getThread() == null) {

chat = getUserChat(message.getFrom());

}

else {

chat = getThreadChat(message.getThread());

}

if(chat == null) {

                chat = createChat(message);

            }

deliverMessage(chat, message);

}

As you can see, createChat(Message) checks for a null “thread”, but not a null “from”:

private Chat createChat(Message message) {

String threadID = message.getThread();

if(threadID == null) {

threadID = nextID();

}

String userJID = message.getFrom();

   return createChat(userJID, threadID, false);

}

So a null userJID will be passed to createChat(String userJID, String threadID, boolean). It uses both String parameters as Map keys:

private Chat createChat(String userJID, String threadID, boolean createdLocally) {

Chat chat = new Chat(this, userJID, threadID);

threadChats.put(threadID, chat);

jidChats.put(userJID, chat);

baseJidChats.put(StringUtils.parseBareAddress(userJID), chat);

for(ChatManagerListener listener : chatManagerListeners) {

listener.chatCreated(chat, createdLocally);

}

    return chat;

}

Unfortunately, the documentation on ReferenceMap (the implementation used for jidChats) warns:

“This java.util.Map implementation does *not *allow null elements. Attempting to add a null key or value to the map will raise a NullPointerException.”, so that’s just what it does - throws a NPE.

For my purposes, I just reorganized the logic in processPacket(Packet) and added a check to make sure that it doesn’t try to create a chat if there is no “from” attribute. Then, it just doesn’t deliver the packet if no existing chat was found. I don’t know if there’d ever be a reason you’d want to do more with it. I thought about substituting an empty string in as the userJID, but I didn’t need to process that packet, and it’s probably better that someone more familiar with XMPP decide how to handle it.

Note: I took a peek into the main branch and it looks like the same issue would occur there, too.

Russ

Seems like a minor bug in Smack.

From RFC 6120:

when a client receives a stanza that does not include a ‘from’ attribute, it MUST assume that the stanza is from the user’s account on the server.

Filed as SMACK-551

You can switch chat manager off, for non-chat messages to workaround it. The method is: chatmanager.setNormalIncluded(false).

1 Like