powered by Jive Software

IQ request stanzas are not delivered to stanza listeners

I wrote a small test client using 4.4.0-alpha2. I added some code that intents to log all stanzas (and major events), by doing this:

connection.addAsyncStanzaListener( stanza -> Log.info( "Recv: {}", stanza.toXML() ), stanza -> true );
connection.addStanzaSendingListener( stanza -> Log.info( "Send: {}", stanza.toXML() ), stanza -> true );
connection.addStanzaDroppedListener( stanza -> Log.warn( "Dropped: {}", stanza.toXML() ) );
connection.addConnectionListener(new ConnectionListener() {
    @Override public void connected( final XMPPConnection xmppConnection ) { Log.info("Connected"); }
    @Override public void authenticated( final XMPPConnection xmppConnection, final boolean b ) { Log.info("authenticated: {}", b); }
    @Override public void connectionClosed() { Log.warn("Connection closed"); }
    @Override public void connectionClosedOnError( final Exception e ) { Log.warn("Connection closed with error", e); }

This generated the following log file.

20:15:42.474 client-1: Connected
20:15:42.618 client-1: Send: <iq xmlns='jabber:client' id='TSVEF-3' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>client-1</resource></bind></iq>
20:15:42.621 client-1: Recv: <iq xmlns='jabber:client' to='laptop-guus/7eui9smspz' id='TSVEF-3' type='result'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>leela@laptop-guus/client-1</jid></bind></iq>
20:15:42.626 client-1: Send: <iq xmlns='jabber:client' id='TSVEF-5' type='get'><query xmlns='jabber:iq:roster'></query></iq>
20:15:42.627 client-1: authenticated: false
\20:15:42.627 client-1: Recv: <iq xmlns='jabber:client' to='leela@laptop-guus/client-1' id='TSVEF-5' type='result'><query xmlns='jabber:iq:roster' ver='102849665'></query></iq>
20:15:42.630 client-1: Send: <presence xmlns='jabber:client' id='TSVEF-7'><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://igniterealtime.org/projects/smack' ver='NfJ3flI83zSdUDzCEICtbypursw='/></presence>
20:15:42.634 client-1: Recv: <presence xmlns='jabber:client' to='leela@laptop-guus/client-1' from='leela@laptop-guus/client-1' id='TSVEF-7'><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://igniterealtime.org/projects/smack' ver='NfJ3flI83zSdUDzCEICtbypursw='/></presence>
20:15:47.631 client-1: Send: <iq xmlns='jabber:client' to='laptop-guus' id='326-23' type='error'><error xmlns='jabber:client' type='modify'><not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>
20:18:47.830 client-1: Send: <iq xmlns='jabber:client' to='laptop-guus' id='21-24' type='result'></iq>
20:21:48.029 client-1: Send: <iq xmlns='jabber:client' to='laptop-guus' id='930-25' type='result'></iq>

This log contains IQ responses to requests that have not been logged. I expected the code to log everything that’s received, but apparently, that’s not the case. Shouldn’t it?

IQ requests can only be handled by IQ request handlers. Smack deliveratedly prevents them from being delivered to normal stanza listeners so that 1. users do not start to implement IQ request handling in them, potentially leading to issues like multiple listeners handling the same IQ request, and 2., so that Smack is aware which IQ requests are handled and which have to be replied with service-unavaiable because there is no handler registered.

That said, if your intent is to log all stanzas and major events of Smack, then attaching a SmackDebugger to the connection is the way to go.

Your reasoning makes sense, but this behavior does make the API counter-intuitive: as the user can provide a filter, it’s not unreasonable to expect that filter will be applied to all stanzas.

I’m not arguing for changing the behavior of the API, but maybe it’d be good to make things more obvious. I’m not sure what the best way of doing that would be.

At the very least, this behavior should be documented better. That said, I would’ve missed it even if it was. Maybe rename/split the handlers from the generic name to more specific ones (addIQResultListener)?