powered by Jive Software

Problems while managing subscribers in a pubsub node

Hello,

Just to lay things out about my developing environment, I’m using Smack 4.2.4 and Ejabberd 17.04.

I’ve been having some problems with subscription management. What follows, is the code I’m currently using to modify the subscribers list of a node from the current connection user, which I’m making sure to be owner of said node.

	/**
	 * Modifies the subscriptions state from the leaf node informed
	 * Current user (retrieved from the connection) has to be the owner of informed group
	 * */
	private void modifySubscriptionsAsOwner (List<Subscription> subscriptions, String groupId) {

		Objects.requireNonNull(groupId);

		LOGGER.debug("modifySubscriptionsAsOwner: modifying list of subscriber in group {}: {}", groupId, subscriptions);

		try {

			String subscriptionId = String.format("subToNode%s%d", groupId, System.currentTimeMillis());

			PubSub subscriptionsIq = new PubSub(PubSubNamespace.OWNER);

			subscriptionsIq.setType(IQ.Type.set);
			subscriptionsIq.setFrom(jidFromConnection());
			subscriptionsIq.setTo(pubSubJid());
			subscriptionsIq.setStanzaId(subscriptionId);
			subscriptionsIq.addExtension(new SubscriptionsExtension(groupId, subscriptions));

			connection.sendIqWithResponseCallback(subscriptionsIq, new StanzaListener() {
				@Override
				public void processStanza(Stanza packet) {
					LOGGER.debug("Subscribed: {}", packet);
				}
			}, new ExceptionCallback() {
				@Override
				public void processException(Exception e) {
					LOGGER.error("Error response from subscription: ", e);
				}
			});

			LOGGER.debug("modifySubscriptionsAsOwner: done making changes to subscribers list in group {}", groupId);

		} catch (NotConnectedException e) {
			LOGGER.error("Error while subscribing member to node: ", e);
		} catch (InterruptedException e) {
			LOGGER.error("Error while subscribing member from node, interrupting, interrupting thread: : ", e);
			Thread.currentThread().interrupt();
		}

	}

The list of subscriptions passed as parameters is an extension org.jivesoftware.smackx.pubsub.Subscription:

/**
 * Used when making changes to group subscribers state
 * Configuration is always not required
 * */
public class SubscriptionManagementExtension extends Subscription {

    /**
     * Used when altering subscription state as an owner.
     * Node id added in {@link SubscriptionsExtension}
     *
     * In this class, just passing subscriber id and state
     * */
    private SubscriptionManagementExtension(Jid subscriptionJid, Subscription.State state) {
        super(subscriptionJid.toString());
        super.state = state;
    }

    public static SubscriptionManagementExtension subscribe(Jid subscriptionJid) {
        return new SubscriptionManagementExtension(subscriptionJid, State.subscribed);
    }
}

After sending the IQ, this is what I get as the resulting stream, conforming to what is defined in XEP-0060:

<iq to="pubsub.mydomain.com.br" id="subToNode308699021565388197042" type="set">
   <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
      <subscriptions node="30869902">
         <subscription jid="03993460@mydomain.com.br/29441670167803215722004" subscription="subscribed" />
      </subscriptions>
   </pubsub>
</iq>

And just like described by XMPP pubsub specification, I get the answer that my subscription state has been altered:

<message to="03993460@mydomain.com.br/29441670167803215722004" from="pubsub.mydomain.com.br">
   <event xmlns="http://jabber.org/protocol/pubsub#event">
      <subscription subscription="subscribed" node="30869902" jid="03993460@mydomain.com.br/29441670167803215722004" />
   </event>
</message>

The thing is, for some reason, such message cannot be processed by Smack. What follows is the full stack trace of the exception thrown when trying to cast the result:

ago 09, 2019 7:03:17 PM org.jivesoftware.smack.AbstractXMPPConnection callConnectionClosedOnErrorListener
WARNING: Connection XMPPTCPConnection[03993460@mydomain.com.br/29441670167803215722004] (0) closed with error
java.lang.ClassCastException: class org.jivesoftware.smack.packet.StandardExtensionElement cannot be cast to class org.jivesoftware.smackx.pubsub.NodeExtension (org.jivesoftware.smack.packet.StandardExtensionElement and org.jivesoftware.smackx.pubsub.NodeExtension are in unnamed module of loader 'app')
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:40)
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:35)
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:105)
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:82)
	at org.jivesoftware.smack.provider.Provider.parse(Provider.java:43)
	at org.jivesoftware.smack.util.PacketParserUtils.parseExtensionElement(PacketParserUtils.java:935)
	at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1045)
	at org.jivesoftware.smack.util.PacketParserUtils.parseMessage(PacketParserUtils.java:285)
	at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:151)
	at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:1083)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$500(XMPPTCPConnection.java:151)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1044)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:1000)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1016)
	at java.base/java.lang.Thread.run(Thread.java:834)

Aug 09 19:03:17 ERROR XMPPConnectionListener - connectionClosedOnError
java.lang.ClassCastException: class org.jivesoftware.smack.packet.StandardExtensionElement cannot be cast to class org.jivesoftware.smackx.pubsub.NodeExtension (org.jivesoftware.smack.packet.StandardExtensionElement and org.jivesoftware.smackx.pubsub.NodeExtension are in unnamed module of loader 'app')
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:40) ~[smack-extensions-4.2.4.jar:4.2.4]
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:35) ~[smack-extensions-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:105) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:82) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.provider.Provider.parse(Provider.java:43) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.util.PacketParserUtils.parseExtensionElement(PacketParserUtils.java:935) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1045) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.util.PacketParserUtils.parseMessage(PacketParserUtils.java:285) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:151) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:1083) ~[smack-core-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$500(XMPPTCPConnection.java:151) [smack-tcp-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1044) [smack-tcp-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:1000) [smack-tcp-4.2.4.jar:4.2.4]
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1016) [smack-tcp-4.2.4.jar:4.2.4]
	at java.lang.Thread.run(Thread.java:834) [?:?]
Aug 09 19:03:17 INFO  ConnectionListener - Connection closed on error
19:03:17 XMPPConnection closed due to an exception (XMPPTCPConnection[03993460@mydomain.com.br/29441670167803215722004] (0))java.lang.ClassCastException: class org.jivesoftware.smack.packet.StandardExtensionElement cannot be cast to class org.jivesoftware.smackx.pubsub.NodeExtension (org.jivesoftware.smack.packet.StandardExtensionElement and org.jivesoftware.smackx.pubsub.NodeExtension are in unnamed module of loader 'app')
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:40)
	at org.jivesoftware.smackx.pubsub.provider.EventProvider.createReturnExtension(EventProvider.java:35)
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:105)
	at org.jivesoftware.smack.provider.EmbeddedExtensionProvider.parse(EmbeddedExtensionProvider.java:82)
	at org.jivesoftware.smack.provider.Provider.parse(Provider.java:43)
	at org.jivesoftware.smack.util.PacketParserUtils.parseExtensionElement(PacketParserUtils.java:935)
	at org.jivesoftware.smack.util.PacketParserUtils.addExtensionElement(PacketParserUtils.java:1045)
	at org.jivesoftware.smack.util.PacketParserUtils.parseMessage(PacketParserUtils.java:285)
	at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:151)
	at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:1083)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$500(XMPPTCPConnection.java:151)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1044)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:1000)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1016)
	at java.base/java.lang.Thread.run(Thread.java:834)

I get disconnected, as is expected from Smack specification in such scenarios. What i don’t get is what is causing the error. When I get reconnected, and try to retrieve the list of subscribed nodes just to confirm that the the operation is being successful.

Thanks in advance for the help. Lemme know if you guys need more information about what I’m doing.