org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=hzWso-48)), : fromFilter (OrFilter: (FromMatchesFilter (full): +601156915186@hetero.io, FromMatchesFilter (full): null)).
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:265)
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:219)
at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.discoverInfo(ServiceDiscoveryManager.java:531)
at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.discoverInfo(ServiceDiscoveryManager.java:505)
at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.supportsFeatures(ServiceDiscoveryManager.java:738)
at org.jivesoftware.smackx.disco.ServiceDiscoveryManager.supportsFeatures(ServiceDiscoveryManager.java:734)
at org.jivesoftware.smackx.pep.PEPManager.isSupported(PEPManager.java:177)
at io.hetero.communique.pep.SecureChat.publishSecureChatEvent(SecureChat.java:65)
at io.hetero.communique.connection.Connection.run(Connection.java:713)
at io.hetero.communique.connection.Connection$3.run(Connection.java:423)
No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=hzWso-48)), : fromFilter (OrFilter: (FromMatchesFilter (full): +601156915186@hetero.io, FromMatchesFilter (full): null)).
You figured that an NPE will be thrown if you use null as argument, and that an more or less invalid IQ request will be send if you use the empty string as argument. So how about using a non-empty String as argument?
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 60000ms (~60s). Waited for response using: IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=RvvQ3-50)), : fromFilter (OrFilter: (FromMatchesFilter (full): user@example.com, FromMatchesFilter (full): null)).
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:265)
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:219)
at org.jivesoftware.smackx.pubsub.PubSubManager.getNode(PubSubManager.java:240)
at org.jivesoftware.smackx.pep.PEPManager.publish(PEPManager.java:157)
As you can see in the example I’ve taken from XEP-0163, there is no node attribute. According to this answer in MongooseIM forum, the presence of node attribute makes it an invalid request. In other words, if the request contains a node attribute, MongooseIM will ignore the request and will not respond. Whether the node attribute is empty or otherwise is irrelevant.
It probably doesn’t make any sense to info query for a node (in PEP), but IMO the server should just return (or the same as it would return with no node attribute):
First, It helps to re-use Smack’s existing PubSub implementation. After all PEP is just PubSub on a user account with a well defined mandatory feature set. This alone requires the PEP service to answer the request.
Granted, there are currently no PEP specifications which use mixed Collection- and Leaf-Nodes, but the day will eventually come. And then you need to determine the mode type.
Besides that, it makes the API easier to use and less error prone: Smack will return a different node APO depending on the node type, as collection nodes and lead nodes provide a different set of operations
That was no critic on Smack’s API, but just from a user’s (or use-case) point of view, I see no motivation to pass a node. (for the reasons you mentioned).
PEP API reusing existing PubSub API is obviously the best approach.