Smack在名册的状态侦听器中引发NullPointerException

时间:2018-10-26 10:22:57

标签: xmpp smack

我正在将Smack与android聊天应用程序一起使用,最近我已将Smack更新到版本4.3.0,并且在结构中出现了一些错误。这是Smack内部的NullPointerException

Fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:772)
org.jivesoftware.smack.roster.Roster.getPresencesInternal (Roster.java:374)
org.jivesoftware.smack.roster.Roster.getOrCreatePresencesInternal (Roster.java:388)
org.jivesoftware.smack.roster.Roster.access$1100 (Roster.java:94)
org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run (Roster.java:1502)
org.jivesoftware.smack.AsyncButOrdered$Handler.run (AsyncButOrdered.java:121)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
java.lang.Thread.run (Thread.java:818)

1 个答案:

答案 0 :(得分:1)

  

“使用Luke的源代码(并研究相关的开放标准)” Obi-Wan Kenobi

零食开放,所以让我们看一下源代码:

org.jivesoftware.smack.roster.Roster.getPresencesInternal (Roster.java:374)

显示为

Map<Resourcepart, Presence> entityPresences = presenceMap.get(entity);

来源:https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L374

我们还发现presenceMap声明如下

private final Map<BareJid, Map<Resourcepart, Presence>> presenceMap = new ConcurrentHashMap<>();

来源:https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L168

因此它是ConcurrentHashMap,与stacktrace匹配。显而易见,上面的entitynull,这是NullPointerException的原因。

现在,我们需要向上(或向下,取决于您的角度)调用堆栈,以确定entity的来源。这里有趣的部分是

org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run (Roster.java:1502)

显示为

userPresences = getOrCreatePresencesInternal(key);

来源:https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L1562

所以这里的enittykey。在上面声明并定义了几行

final BareJid key = from != null ? from.asBareJid() : null;

来源:https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L1562

因此,如果from是来自属性集的null,will also be null. Which later causes the NullPointerException . Looking at the code, we find that this is caused by a presence XMPP stanza without a

现在的问题是,这些节在XMPP中是否合法。为了确定这一点,我们需要看一下规范。相关部分是[RFC 6120§8.1.2.1 4。],1,指出

  

当服务器从服务器生成节以进行交付时   代表关联客户的帐户给客户   (例如,在由   服务器代表客户端),该节必须(a)不   包含“来自”属性或(b)包含“来自”属性   其值为帐户的原始JID()。

因此通常允许缺少'from'属性,该属性等于“帐户的原始JID”。

现在的问题是:是否有指定的从服务器发送到客户端的在场节没有'from'属性?阅读相关的RFC 6121时找不到任何内容。而且我不知道何时应该发生这种情况(我可能会遗漏一些东西)。但是,现在看来,这似乎是实体中的一个错误,该错误会创建这些存在节,即使用的XMPP服务器实现。

(您使用哪种XMPP服务器实现?)。