diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
index 4ddac7757..793b5b852 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java
@@ -422,26 +422,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
// Note that we can not use IQReplyFilter here, since the users full JID is not yet
// available. It will become available right after the resource has been successfully bound.
Bind bindResource = Bind.newSet(resource);
- PacketCollector packetCollector = createPacketCollector(new PacketIDFilter(bindResource));
- try {
- sendPacket(bindResource);
- } catch (NotConnectedException e) {
- packetCollector.cancel();
- throw e;
- }
+ PacketCollector packetCollector = createPacketCollectorAndSend(new PacketIDFilter(bindResource), bindResource);
Bind response = packetCollector.nextResultOrThrow();
user = response.getJid();
setServiceName(XmppStringUtils.parseDomain(user));
if (hasFeature(Session.ELEMENT, Session.NAMESPACE) && !getConfiguration().isLegacySessionDisabled()) {
Session session = new Session();
- packetCollector = createPacketCollector(new PacketIDFilter(session));
- try {
- sendPacket(session);
- } catch (NotConnectedException e) {
- packetCollector.cancel();
- throw e;
- }
+ packetCollector = createPacketCollectorAndSend(new PacketIDFilter(session), session);
packetCollector.nextResultOrThrow();
}
}
@@ -639,12 +627,20 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
public PacketCollector createPacketCollectorAndSend(IQ packet) throws NotConnectedException {
PacketFilter packetFilter = new IQReplyFilter(packet, this);
// Create the packet collector before sending the packet
+ PacketCollector packetCollector = createPacketCollectorAndSend(packetFilter, packet);
+ return packetCollector;
+ }
+
+ @Override
+ public PacketCollector createPacketCollectorAndSend(PacketFilter packetFilter, Packet packet)
+ throws NotConnectedException {
+ // Create the packet collector before sending the packet
PacketCollector packetCollector = createPacketCollector(packetFilter);
try {
// Now we can send the packet as the collector has been created
sendPacket(packet);
}
- catch (NotConnectedException e) {
+ catch (NotConnectedException | RuntimeException e) {
packetCollector.cancel();
throw e;
}
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java
index 66f9f1813..093f36677 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java
@@ -208,6 +208,26 @@ public interface XMPPConnection {
* a specific result.
*
* @param packetFilter the packet filter to use.
+ * @param packet the packet to send right after the collector got created
+ * @return a new packet collector.
+ */
+ public PacketCollector createPacketCollectorAndSend(PacketFilter packetFilter, Packet packet)
+ throws NotConnectedException;
+
+ /**
+ * Creates a new packet collector for this connection. A packet filter
+ * determines which packets will be accumulated by the collector. A
+ * PacketCollector is more suitable to use than a {@link PacketListener}
+ * when you need to wait for a specific result.
+ *
+ * Note: If you send a Packet right after using this method, then
+ * consider using
+ * {@link #createPacketCollectorAndSend(PacketFilter, Packet)} instead.
+ * Otherwise make sure cancel the PacketCollector in every case, e.g. even
+ * if an exception is thrown, or otherwise you may leak the PacketCollector.
+ *
+ *
+ * @param packetFilter the packet filter to use.
* @return a new packet collector.
*/
public PacketCollector createPacketCollector(PacketFilter packetFilter);
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java
index 6feb8e04d..3a9792ca5 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java
@@ -80,10 +80,9 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
}
public InputStream createIncomingStream(StreamInitiation initiation) throws SmackException {
- PacketCollector collector = connection.createPacketCollector(
- getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));
-
- connection.sendPacket(super.createInitiationAccept(initiation, getNamespaces()));
+ PacketCollector collector = connection.createPacketCollectorAndSend(
+ getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()),
+ super.createInitiationAccept(initiation, getNamespaces()));
ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(2);
CompletionService service
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
index f4f3db1b3..92dc82878 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java
@@ -79,8 +79,7 @@ public abstract class StreamNegotiator {
// establish collector to await response
PacketCollector collector = connection
- .createPacketCollector(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()));
- connection.sendPacket(response);
+ .createPacketCollectorAndSend(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID()), response);
Packet streamMethodInitiation = collector.nextResultOrThrow();
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
index 212a49065..1111731c1 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
@@ -290,8 +290,7 @@ public class AccountManager extends Manager {
}
private PacketCollector createPacketCollectorAndSend(IQ req) throws NotConnectedException {
- PacketCollector collector = connection().createPacketCollector(new PacketIDFilter(req.getPacketID()));
- connection().sendPacket(req);
+ PacketCollector collector = connection().createPacketCollectorAndSend(new PacketIDFilter(req.getPacketID()), req);
return collector;
}
}
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
index f0a6ed0e7..ac707e635 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java
@@ -469,9 +469,7 @@ public class MultiUserChat {
+ nickname), new PacketTypeFilter(Presence.class));
PacketCollector response = null;
- response = connection.createPacketCollector(responseFilter);
- // Send join packet.
- connection.sendPacket(joinPresence);
+ response = connection.createPacketCollectorAndSend(responseFilter, joinPresence);
// Wait up to a certain number of seconds for a reply.
Presence presence = (Presence) response.nextResultOrThrow(timeout);
@@ -1080,9 +1078,7 @@ public class MultiUserChat {
new AndFilter(
FromMatchesFilter.createFull(room + "/" + nickname),
new PacketTypeFilter(Presence.class));
- PacketCollector response = connection.createPacketCollector(responseFilter);
- // Send join packet.
- connection.sendPacket(joinPresence);
+ PacketCollector response = connection.createPacketCollectorAndSend(responseFilter, joinPresence);
// Wait up to a certain number of seconds for a reply. If there is a negative reply, an
// exception will be thrown
response.nextResultOrThrow();
@@ -1905,9 +1901,7 @@ public class MultiUserChat {
return subject.equals(msg.getSubject());
}
});
- PacketCollector response = connection.createPacketCollector(responseFilter);
- // Send change subject packet.
- connection.sendPacket(message);
+ PacketCollector response = connection.createPacketCollectorAndSend(responseFilter, message);
// Wait up to a certain number of seconds for a reply.
response.nextResultOrThrow();
}
diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
index f0a92624e..9fbcc9621 100644
--- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
+++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java
@@ -301,9 +301,8 @@ public class AgentSession {
presence.addExtension(new DefaultPacketExtension(AgentStatus.ELEMENT_NAME,
AgentStatus.NAMESPACE));
- PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)));
-
- connection.sendPacket(presence);
+ PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter(
+ new PacketTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence);
presence = (Presence)collector.nextResultOrThrow();
@@ -401,11 +400,9 @@ public class AgentSession {
presence.addExtension(agentStatus);
presence.addExtension(new MetaData(this.metaData));
- PacketCollector collector = this.connection.createPacketCollector(new AndFilter(
+ PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter(
new PacketTypeFilter(Presence.class),
- FromMatchesFilter.create(workgroupJID)));
-
- this.connection.sendPacket(presence);
+ FromMatchesFilter.create(workgroupJID)), presence);
collector.nextResultOrThrow();
}
@@ -447,10 +444,8 @@ public class AgentSession {
}
presence.addExtension(new MetaData(this.metaData));
- PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class),
- FromMatchesFilter.create(workgroupJID)));
-
- this.connection.sendPacket(presence);
+ PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter(new PacketTypeFilter(Presence.class),
+ FromMatchesFilter.create(workgroupJID)), presence);
collector.nextResultOrThrow();
}
diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java
index 3aeacb296..831fc7ac0 100644
--- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java
+++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java
@@ -180,10 +180,8 @@ public class Workgroup {
directedPresence.setTo(workgroupJID);
PacketFilter typeFilter = new PacketTypeFilter(Presence.class);
PacketFilter fromFilter = FromMatchesFilter.create(workgroupJID);
- PacketCollector collector = connection.createPacketCollector(new AndFilter(fromFilter,
- typeFilter));
-
- connection.sendPacket(directedPresence);
+ PacketCollector collector = connection.createPacketCollectorAndSend(new AndFilter(fromFilter,
+ typeFilter), directedPresence);
Presence response = (Presence)collector.nextResultOrThrow();
return Presence.Type.available == response.getType();