我正在将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)
答案 0 :(得分:1)
“使用Luke的源代码(并研究相关的开放标准)” Obi-Wan Kenobi
零食开放,所以让我们看一下源代码:
org.jivesoftware.smack.roster.Roster.getPresencesInternal (Roster.java:374)
显示为
Map<Resourcepart, Presence> entityPresences = presenceMap.get(entity);
我们还发现presenceMap
声明如下
private final Map<BareJid, Map<Resourcepart, Presence>> presenceMap = new ConcurrentHashMap<>();
因此它是ConcurrentHashMap
,与stacktrace匹配。显而易见,上面的entity
是null
,这是NullPointerException
的原因。
现在,我们需要向上(或向下,取决于您的角度)调用堆栈,以确定entity
的来源。这里有趣的部分是
org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run (Roster.java:1502)
显示为
userPresences = getOrCreatePresencesInternal(key);
所以这里的enitty
是key
。在上面声明并定义了几行
final BareJid key = from != null ? from.asBareJid() : null;
因此,如果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服务器实现?)。