Previously, if a SmackFuture both was successful and unsuccessful, it
was possible that the onSuccess() callback was invoked twice.
Reported-by: Boris Grozev <boris@jitsi.org>
All other enum-using methods of XmlStringBuilder already use
Enum.toString(), as opposed to Enum.name(), this was the only left. I
do not remember why I did not to change this method too, probably
because of its plenty call sites.
But since this method already broke Jingle XML serializaton,
JingleAction was e.g., 'session_accept' when it should be
'session-accept', we change it now.
Fixes SMACK-921.
Connections like XMPPTCPConnection may still reported connected, if
they are, for example disconnected but resumable. This is already
accounted for in throwAlreadyConnectedExceptionIfAppropriate(), hence
the assert is unnecessary and leads to false negatives for
XMPPTCPConnection.
For the sake of completeness, the right condition, assuming
XMPPTCPConnection is used, for the assert would be:
assert !connected || disconnectedButResumable;
This allows to avoid redundant XML namespaces within IQs, like for
example here:
<iq xmlns='jabber:client' id='EKP8I-1' type='set'>
<jingle xmlns='urn:xmpp:jingle:1' action='content-accept' sid='MySession'>
<content xmlns='urn:xmpp:jingle:1' creator='initiator' name='Hello world'>
</content>
</jingle>
</iq>
Fixes SMACK-917
Reported-by: Jonathan Lennox
Appearently simply calling ClassLoader.getSystemResourceAsStream()
works on Java SE but not on Android. But our FileUtils are able to
load the resource stream on Android.
Assume the element
<foo:bar xmlns='namespace' xmlns:foo='foo-namespace'/>
then the <bar/> element's namespace is 'foo-namespace', but the
default namespace is 'namespace'. And this is the namespace that
scopes into inner elements.
aTalk shows the following exception:
2020-12-14 12:11:13.704 7370-30976/org.atalk.android E/AndroidRuntime: FATAL EXCEPTION: AccountManager.loadStoredAccounts
Process: org.atalk.android, PID: 7370
java.lang.AssertionError: Element type 'EE' is neither of type Class or ParameterizedType
at org.jivesoftware.smack.provider.AbstractProvider.<init>(AbstractProvider.java:46)
at org.jivesoftware.smack.provider.Provider.<init>(Provider.java:40)
at org.jivesoftware.smack.provider.ExtensionElementProvider.<init>(ExtensionElementProvider.java:29)
at org.xmpp.extensions.DefaultExtensionElementProvider.<init>(DefaultExtensionElementProvider.java:43)
at org.xmpp.extensions.coin.CoinIQProvider.<init>(CoinIQProvider.java:46)
at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderServiceJabberImpl.initialize(ProtocolProviderServiceJabberImpl.java:2091)
at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderFactoryJabberImpl.createService(ProtocolProviderFactoryJabberImpl.java:121)
at net.java.sip.communicator.service.protocol.ProtocolProviderFactory.loadAccount(ProtocolProviderFactory.java:934)
at net.java.sip.communicator.service.protocol.AccountManager.doLoadStoredAccounts(AccountManager.java:139)
at net.java.sip.communicator.service.protocol.AccountManager.loadStoredAccounts(AccountManager.java:294)
at net.java.sip.communicator.service.protocol.AccountManager.runInLoadStoredAccountsThread(AccountManager.java:394)
at net.java.sip.communicator.service.protocol.AccountManager.access$000(AccountManager.java:36)
at
net.java.sip.communicator.service.protocol.AccountManager$1.run(AccountManager.java:329)
where CoinIQProvider line 46-47 [1] reads
private final DefaultExtensionElementProvider<URIsExtension> urisProvider
= new
DefaultExtensionElementProvider<>(URIsExtension.class);
This fixes SMACK-898.
1: f61f264312/aTalk/src/main/java/org/xmpp/extensions/coin/CoinIQProvider.java (L47)
Do net put an ack to the queue if it has already been shutdown. Some
servers, like ejabberd, like to request an ack even after we have send
a stream close (and hance the queue was shutdown). If we would not
check here, then the ack would dangle around in the queue, and be send
on the next re-connection attempt even before the stream open.
See the following trace of the MUC bookmarks integration test. The
fact that it is a MUC test does not matter, but this test does
disconnect the connection and reconnect it. Not how the server,
ejabberd in this case, requests an SM ack by sending an <r/> even
though we already send the </stream:stream>:
22:22:05 SENT (4):
<iq id='MD4UC-61' type='set'>
<query xmlns='jabber:iq:private'>
<storage xmlns='storage:bookmarks'>
<conference name='Smack Inttest: 7in7j' autojoin='true' jid='y9jcn5@conference.salem.geekplace.eu'>
<nick>
Nick-P2VXD7
</nick>
</conference>
</storage>
</query>
</iq>
22:22:05 RECV (4):
<r xmlns='urn:xmpp:sm:3'/>
22:22:05 SENT (4):
<a xmlns='urn:xmpp:sm:3' h='29'/>
22:22:05 RECV (4):
<message to='sinttest-7in7j-4@salem.geekplace.eu' from='sinttest-7in7j-4@salem.geekplace.eu' type='headline'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='storage:bookmarks'>
<item id='current'>
<storage xmlns='storage:bookmarks'>
<conference name='Smack Inttest: 7in7j' autojoin='true' jid='y9jcn5@conference.salem.geekplace.eu'>
<nick>
Nick-P2VXD7
</nick>
</conference>
</storage>
</item>
</items>
</event>
<addresses xmlns='http://jabber.org/protocol/address'>
<address jid='sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090' type='replyto'/>
</addresses>
</message>
22:22:05 RECV (4):
<iq xml:lang='en-US' to='sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090' from='sinttest-7in7j-4@salem.geekplace.eu' type='result' id='MD4UC-61'/>
22:22:05 SENT (4):
<presence id='6MS6J-20' type='unavailable'/>
<a xmlns='urn:xmpp:sm:3' h='31'/>
<!-- We have closed the stream -->
</stream:stream>
<!-- But the server still requests an SM ack -->
22:22:05 RECV (4):
<r xmlns='urn:xmpp:sm:3'/>
22:22:05 RECV (4):
</stream:stream>
22:22:05 XMPPConnection closed (XMPPTCPConnection[sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090] (4))
22:22:05 SENT (4):
<a xmlns='urn:xmpp:sm:3' h='31'/>
22:22:05 SENT (4):
<stream:stream xmlns='jabber:client' to='salem.geekplace.eu' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='sinttest-7in7j-4@salem.geekplace.eu' xml:lang='en-US'>
22:22:05 RECV (4): ?xml version='1.0'?>
<stream:stream id='3379123514446782311' ver
22:22:05 RECV (4): sion='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'>
<stream:error>
<invalid-xml xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
</stream:stream>
22:22:05 XMPPConnection closed due to an exception (XMPPTCPConnection[sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090] (4))
org.jivesoftware.smack.XMPPException$StreamErrorException: invalid-xml You can read more about the meaning of this stream error at http://xmpp.org/rfcs/rfc6120.html#streams-error-conditions
<stream:error><invalid-xml xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:981)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$700(XMPPTCPConnection.java:913)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:936)
at java.base/java.lang.Thread.run(Thread.java:834)
Smack currently does unnecessary escaping of XML text, where it
escapes e.g. '"' to '"'. This bloats the stanza size, especially
if JSON payloads are involved.
Fixes SMACK-892 (although there are probably still places where
XmlStringBuilder.escape() is used when XmlStringBuild.text() could
have been used).
This means that users get now exceptions with helpful error messages
instead of the dreaded ClassCastException, like
java.lang.ClassCastException: org.jivesoftware.smack.packet.StandardExtensionElement cannot be cast to org.jivesoftware.smackx.mam.element.MamElements$MamResultExtension
at
when StanzaView.getExtension(Class) is used to retrieve the extension.