Smack генерирует исключение NullPointerException в слушателе присутствия Ростера - PullRequest
0 голосов
/ 26 октября 2018

Я использую Smack с приложениями для общения в Android, и недавно я обновил Smack до версии 4.3.0 и получил ошибку в ткани.Это NullPointerException внутри Smack:

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 голосов
/ 26 октября 2018

«Используй источник, Люк (и изучай соответствующий открытый стандарт)» Оби-Ван Кеноби

Smack - открытый источник, поэтому давайте посмотрим на источник: одна интересная часть -

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, который совпадает с трассировкой стека. Очевидно, что entity выше - null, что является причиной 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

поэтому enitty здесь key. Который объявить и определить всего несколькими строками выше

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 from` установлен атрибут.

Вопрос теперь в том, допустимы ли эти строфы в XMPP. Чтобы определить это, нам нужно взглянуть на спецификацию. Соответствующей частью является [RFC 6120 § 8.1.2.1 4.], 1 , в котором говорится

Когда сервер генерирует раздел из сервера для доставки клиенту от имени учетной записи подключенного клиента (например, в контексте услуг хранения данных, предоставляемых сервер от имени клиента), раздел ДОЛЖЕН либо (а) не включить атрибут «из» или (б) включить атрибут «из» значение которого является чистым JID учетной записи ().

Таким образом, пропущенный атрибут 'from', как правило, разрешен и равен «чистому JID учетной записи».

Теперь возникает вопрос: существуют ли какие-либо разделы присутствия, отправленные с сервера клиенту, которые не имеют атрибута from? Я не смог найти ни одного во время чтения связанных RFC 6121 . И я не знаю, когда это когда-либо случится (возможно, мне не хватает чего-то). Но сейчас это похоже на ошибку в сущности, которая создает те строфы присутствия, которые являются реализацией используемого сервера XMPP.

(Какую реализацию сервера XMPP вы используете?).

...