1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-10 17:49:38 +02:00

"not connected" is now a checked Exception thrown by sendPacket()

There is a unsolveable race condition between the connection state and
sendPacket(), i.e. the connection could go down, right after the
method calling sendPacket is called, but before sendPacket() is
invoked. Before this change, sendPacket() has thrown an unchecked
IllegalStateException, which could be ignored by the Smack user, who
would also not notice the race condition. We have decided to throw a
checked Exception in this case now, to make the Smack user aware of
this situation.

SMACK-426
This commit is contained in:
Florian Schmaus 2014-03-19 14:22:20 +01:00
parent d8c656270e
commit fcc8414a92
101 changed files with 845 additions and 382 deletions

View file

@ -24,6 +24,7 @@ import java.util.Map;
import java.util.WeakHashMap;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Registration;
@ -89,8 +90,9 @@ public class AccountManager extends Manager {
* @return true if the server support creating new accounts.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*/
public boolean supportsAccountCreation() throws NoResponseException, XMPPErrorException {
public boolean supportsAccountCreation() throws NoResponseException, XMPPErrorException, NotConnectedException {
// Check if we already know that the server supports creating new accounts
if (accountCreationSupported) {
return true;
@ -130,8 +132,9 @@ public class AccountManager extends Manager {
* @return the required account attributes.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*/
public Collection<String> getAccountAttributes() throws NoResponseException, XMPPErrorException {
public Collection<String> getAccountAttributes() throws NoResponseException, XMPPErrorException, NotConnectedException {
if (info == null) {
getRegistrationInfo();
}
@ -152,8 +155,9 @@ public class AccountManager extends Manager {
* attribute wasn't found for the requested name.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*/
public String getAccountAttribute(String name) throws NoResponseException, XMPPErrorException {
public String getAccountAttribute(String name) throws NoResponseException, XMPPErrorException, NotConnectedException {
if (info == null) {
getRegistrationInfo();
}
@ -168,8 +172,9 @@ public class AccountManager extends Manager {
* @return the account creation instructions, or <tt>null</tt> if there are none.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*/
public String getAccountInstructions() throws NoResponseException, XMPPErrorException {
public String getAccountInstructions() throws NoResponseException, XMPPErrorException, NotConnectedException {
if (info == null) {
getRegistrationInfo();
}
@ -188,8 +193,9 @@ public class AccountManager extends Manager {
* @param password the password.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*/
public void createAccount(String username, String password) throws NoResponseException, XMPPErrorException {
public void createAccount(String username, String password) throws NoResponseException, XMPPErrorException, NotConnectedException {
// Create a map for all the required attributes, but give them blank values.
Map<String, String> attributes = new HashMap<String, String>();
for (String attributeName : getAccountAttributes()) {
@ -208,10 +214,11 @@ public class AccountManager extends Manager {
* @param attributes the account attributes.
* @throws XMPPErrorException if an error occurs creating the account.
* @throws NoResponseException if there was no response from the server.
* @throws NotConnectedException
* @see #getAccountAttributes()
*/
public void createAccount(String username, String password, Map<String, String> attributes)
throws NoResponseException, XMPPErrorException {
throws NoResponseException, XMPPErrorException, NotConnectedException {
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(connection().getServiceName());
@ -229,8 +236,9 @@ public class AccountManager extends Manager {
* @throws IllegalStateException if not currently logged-in to the server.
* @throws XMPPErrorException if an error occurs when changing the password.
* @throws NoResponseException if there was no response from the server.
* @throws NotConnectedException
*/
public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException {
public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException {
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(connection().getServiceName());
@ -249,8 +257,9 @@ public class AccountManager extends Manager {
* @throws IllegalStateException if not currently logged-in to the server.
* @throws XMPPErrorException if an error occurs when deleting the account.
* @throws NoResponseException if there was no response from the server.
* @throws NotConnectedException
*/
public void deleteAccount() throws NoResponseException, XMPPErrorException {
public void deleteAccount() throws NoResponseException, XMPPErrorException, NotConnectedException {
Registration reg = new Registration();
reg.setType(IQ.Type.SET);
reg.setTo(connection().getServiceName());
@ -265,11 +274,12 @@ public class AccountManager extends Manager {
* Gets the account registration info from the server.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
*
* @throws XMPPException if an error occurs.
* @throws SmackException if there was no response from the server.
*/
private synchronized void getRegistrationInfo() throws NoResponseException, XMPPErrorException {
private synchronized void getRegistrationInfo() throws NoResponseException, XMPPErrorException, NotConnectedException {
Registration reg = new Registration();
reg.setTo(connection().getServiceName());
info = (Registration) connection().createPacketCollectorAndSend(reg).nextResultOrThrow();

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smack;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Message;
import java.util.Set;
@ -86,8 +87,9 @@ public class Chat {
*
* @param text the text to send.
* @throws XMPPException if sending the message fails.
* @throws NotConnectedException
*/
public void sendMessage(String text) throws XMPPException {
public void sendMessage(String text) throws XMPPException, NotConnectedException {
Message message = new Message(participant, Message.Type.chat);
message.setThread(threadID);
message.setBody(text);
@ -99,8 +101,9 @@ public class Chat {
* and message type of the message will automatically set to those of this chat.
*
* @param message the message to send.
* @throws NotConnectedException
*/
public void sendMessage(Message message) {
public void sendMessage(Message message) throws NotConnectedException {
// Force the recipient, message type, and thread ID since the user elected
// to send the message through this chat object.
message.setTo(participant);

View file

@ -26,6 +26,7 @@ import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromMatchesFilter;
import org.jivesoftware.smack.filter.PacketFilter;
@ -334,7 +335,7 @@ public class ChatManager extends Manager{
chat.deliver(message);
}
void sendMessage(Chat chat, Message message) {
void sendMessage(Chat chat, Message message) throws NotConnectedException {
for(Map.Entry<PacketInterceptor, PacketFilter> interceptor : interceptors.entrySet()) {
PacketFilter filter = interceptor.getValue();
if(filter != null && filter.accept(message)) {

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smack;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Packet;
/**
@ -40,6 +41,6 @@ public interface PacketListener {
*
* @param packet the packet to process.
*/
public void processPacket(Packet packet);
public void processPacket(Packet packet) throws NotConnectedException;
}

View file

@ -33,6 +33,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.IQReplyFilter;
@ -132,12 +133,22 @@ public class Roster {
public void connectionClosed() {
// Changes the presence available contacts to unavailable
setOfflinePresences();
try {
setOfflinePresences();
}
catch (NotConnectedException e) {
LOGGER.log(Level.SEVERE, "Not connected exception" ,e);
}
}
public void connectionClosedOnError(Exception e) {
// Changes the presence available contacts to unavailable
setOfflinePresences();
try {
setOfflinePresences();
}
catch (NotConnectedException e1) {
LOGGER.log(Level.SEVERE, "Not connected exception" ,e);
}
}
});
@ -146,7 +157,7 @@ public class Roster {
try {
reload();
}
catch (NotLoggedInException e) {
catch (SmackException e) {
LOGGER.log(Level.SEVERE, "Could not reload Roster", e);
}
}
@ -162,7 +173,7 @@ public class Roster {
try {
Roster.this.reload();
}
catch (NotLoggedInException e) {
catch (SmackException e) {
LOGGER.log(Level.SEVERE, "Could not reload Roster", e);
return;
}
@ -205,8 +216,9 @@ public class Roster {
* which means the method will return immediately, and the roster will be
* reloaded at a later point when the server responds to the reload request.
* @throws NotLoggedInException If not logged in.
* @throws NotConnectedException
*/
public void reload() throws NotLoggedInException{
public void reload() throws NotLoggedInException, NotConnectedException{
if (!connection.isAuthenticated()) {
throw new NotLoggedInException();
}
@ -285,9 +297,10 @@ public class Roster {
* @throws NoResponseException if there was no response from the server.
* @throws XMPPErrorException if an XMPP exception occurs.
* @throws NotLoggedInException If not logged in.
* @throws NotConnectedException
* @throws IllegalStateException if logged in anonymously
*/
public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException {
public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
if (!connection.isAuthenticated()) {
throw new NotLoggedInException();
}
@ -325,9 +338,10 @@ public class Roster {
* @throws XMPPErrorException if an XMPP error occurs.
* @throws NotLoggedInException if not logged in.
* @throws NoResponseException SmackException if there was no response from the server.
* @throws NotConnectedException
* @throws IllegalStateException if connection is not logged in or logged in anonymously
*/
public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException {
public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
if (!connection.isAuthenticated()) {
throw new NotLoggedInException();
}
@ -626,8 +640,9 @@ public class Roster {
* Changes the presence of available contacts offline by simulating an unavailable
* presence sent from the server. After a disconnection, every Presence is set
* to offline.
* @throws NotConnectedException
*/
private void setOfflinePresences() {
private void setOfflinePresences() throws NotConnectedException {
Presence packetUnavailable;
for (String user : presenceMap.keySet()) {
Map<String, Presence> resources = presenceMap.get(user);
@ -813,7 +828,7 @@ public class Roster {
*/
private class PresencePacketListener implements PacketListener {
public void processPacket(Packet packet) {
public void processPacket(Packet packet) throws NotConnectedException {
Presence presence = (Presence) packet;
String from = presence.getFrom();
String key = getPresenceMapKey(from);
@ -1024,7 +1039,7 @@ public class Roster {
*/
private class RosterPushListener implements PacketListener {
public void processPacket(Packet packet) {
public void processPacket(Packet packet) throws NotConnectedException {
RosterPacket rosterPacket = (RosterPacket) packet;
if (!rosterPacket.getType().equals(IQ.Type.SET)) {
return;

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smack;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.RosterPacket;
@ -78,8 +79,9 @@ public class RosterEntry {
* Sets the name associated with this entry.
*
* @param name the name.
* @throws NotConnectedException
*/
public void setName(String name) {
public void setName(String name) throws NotConnectedException {
// Do nothing if the name hasn't changed.
if (name != null && name.equals(this.name)) {
return;

View file

@ -24,6 +24,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.RosterPacket;
@ -69,8 +70,9 @@ public class RosterGroup {
* be invalid and will need to be updated to the new group specified by the new name.
*
* @param name the name of the group.
* @throws NotConnectedException
*/
public void setName(String name) {
public void setName(String name) throws NotConnectedException {
synchronized (entries) {
for (RosterEntry entry : entries) {
RosterPacket packet = new RosterPacket();
@ -162,8 +164,9 @@ public class RosterGroup {
* @param entry a roster entry.
* @throws XMPPErrorException if an error occured while trying to add the entry to the group.
* @throws NoResponseException if there was no response from the server.
* @throws NotConnectedException
*/
public void addEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException {
public void addEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException, NotConnectedException {
PacketCollector collector = null;
// Only add the entry if it isn't already in the list.
synchronized (entries) {
@ -192,8 +195,9 @@ public class RosterGroup {
* @param entry a roster entry.
* @throws XMPPErrorException if an error occurred while trying to remove the entry from the group.
* @throws NoResponseException if there was no response from the server.
* @throws NotConnectedException
*/
public void removeEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException {
public void removeEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException, NotConnectedException {
PacketCollector collector = null;
// Only remove the entry if it's in the entry list.
// Remove the entry locally, if we wait for RosterPacketListenerprocess>>Packet(Packet)

View file

@ -18,6 +18,7 @@
package org.jivesoftware.smack;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.ResourceBindingNotOfferedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.Bind;
@ -212,9 +213,10 @@ public class SASLAuthentication {
* @throws NoResponseException
* @throws SASLErrorException
* @throws ResourceBindingNotOfferedException
* @throws NotConnectedException
*/
public String authenticate(String resource, CallbackHandler cbh) throws IOException,
NoResponseException, XMPPErrorException, SASLErrorException, ResourceBindingNotOfferedException {
NoResponseException, XMPPErrorException, SASLErrorException, ResourceBindingNotOfferedException, NotConnectedException {
// Locate the SASLMechanism to use
String selectedMechanism = null;
for (String mechanism : mechanismsPreferences) {
@ -409,7 +411,7 @@ public class SASLAuthentication {
}
private String bindResourceAndEstablishSession(String resource) throws XMPPErrorException,
ResourceBindingNotOfferedException, NoResponseException {
ResourceBindingNotOfferedException, NoResponseException, NotConnectedException {
// Wait until server sends response containing the <bind> element
synchronized (this) {
if (!resourceBinded) {
@ -470,8 +472,9 @@ public class SASLAuthentication {
*
* @param challenge a base64 encoded string representing the challenge.
* @throws IOException If a network error occures while authenticating.
* @throws NotConnectedException
*/
void challengeReceived(String challenge) throws IOException {
void challengeReceived(String challenge) throws IOException, NotConnectedException {
currentMechanism.challengeReceived(challenge);
}
@ -514,7 +517,7 @@ public class SASLAuthentication {
}
}
public void send(Packet stanza) {
public void send(Packet stanza) throws NotConnectedException {
connection.sendPacket(stanza);
}

View file

@ -41,6 +41,7 @@ import java.util.logging.Logger;
import javax.security.sasl.SaslException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.ConnectionException;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.debugger.SmackDebugger;
@ -438,10 +439,11 @@ public abstract class XMPPConnection {
* Sends the specified packet to the server.
*
* @param packet the packet to send.
* @throws NotConnectedException
*/
public void sendPacket(Packet packet) {
public void sendPacket(Packet packet) throws NotConnectedException {
if (!isConnected()) {
throw new IllegalStateException("Not connected to server.");
throw new NotConnectedException();
}
if (packet == null) {
throw new NullPointerException("Packet is null.");
@ -627,8 +629,9 @@ public abstract class XMPPConnection {
*
* @param packet the packet to filter responses from
* @return a new packet collector.
* @throws NotConnectedException
*/
public PacketCollector createPacketCollectorAndSend(IQ packet) {
public PacketCollector createPacketCollectorAndSend(IQ packet) throws NotConnectedException {
PacketFilter packetFilter = new IQReplyFilter(packet, this);
// Create the packet collector before sending the packet
PacketCollector packetCollector = createPacketCollector(packetFilter);
@ -755,7 +758,13 @@ public abstract class XMPPConnection {
private void firePacketSendingListeners(Packet packet) {
// Notify the listeners of the new sent packet
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
listenerWrapper.notifyListener(packet);
try {
listenerWrapper.notifyListener(packet);
}
catch (NotConnectedException e) {
LOGGER.log(Level.WARNING, "Got not connected exception, aborting");
break;
}
}
}
@ -962,6 +971,9 @@ public abstract class XMPPConnection {
for (ListenerWrapper listenerWrapper : recvListeners.values()) {
try {
listenerWrapper.notifyListener(packet);
} catch(NotConnectedException e) {
LOGGER.log(Level.WARNING, "Got not connected exception, aborting", e);
break;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Exception in packet listener", e);
}
@ -1030,8 +1042,9 @@ public abstract class XMPPConnection {
* Notify and process the packet listener if the filter matches the packet.
*
* @param packet the packet which was sent or received.
* @throws NotConnectedException
*/
public void notifyListener(Packet packet) {
public void notifyListener(Packet packet) throws NotConnectedException {
if (packetFilter == null || packetFilter.accept(packet)) {
packetListener.processPacket(packet);
}

View file

@ -17,8 +17,10 @@
package org.jivesoftware.smack.sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import java.io.IOException;
import javax.security.auth.callback.CallbackHandler;
/**
@ -36,20 +38,20 @@ public class SASLAnonymous extends SASLMechanism {
return "ANONYMOUS";
}
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException {
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, NotConnectedException {
authenticate();
}
public void authenticate(String username, String host, String password) throws IOException {
public void authenticate(String username, String host, String password) throws IOException, NotConnectedException {
authenticate();
}
protected void authenticate() throws IOException {
protected void authenticate() throws IOException, NotConnectedException {
// Send the authentication to the server
getSASLAuthentication().send(new AuthMechanism(getName(), null));
}
public void challengeReceived(String challenge) throws IOException {
public void challengeReceived(String challenge) throws IOException, NotConnectedException {
// Build the challenge response stanza encoding the response text
// and send the authentication to the server
getSASLAuthentication().send(new Response());

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smack.sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import java.io.IOException;
import java.util.Map;
@ -55,8 +56,9 @@ public class SASLGSSAPIMechanism extends SASLMechanism {
* @param host the hostname where the user account resides.
* @param cbh the CallbackHandler (not used with GSSAPI)
* @throws IOException If a network error occures while authenticating.
* @throws NotConnectedException
*/
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, SaslException {
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, SaslException, NotConnectedException {
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
props.put(Sasl.SERVER_AUTH,"TRUE");
@ -74,8 +76,9 @@ public class SASLGSSAPIMechanism extends SASLMechanism {
* @param host the hostname where the user account resides.
* @param password the password of the user (ignored for GSSAPI)
* @throws IOException If a network error occures while authenticating.
* @throws NotConnectedException
*/
public void authenticate(String username, String host, String password) throws IOException, SaslException {
public void authenticate(String username, String host, String password) throws IOException, SaslException, NotConnectedException {
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String, String>();
props.put(Sasl.SERVER_AUTH,"TRUE");

View file

@ -17,12 +17,14 @@
package org.jivesoftware.smack.sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.callback.Callback;
@ -129,8 +131,9 @@ public abstract class SASLMechanism implements CallbackHandler {
* @param password the password for this account.
* @throws IOException If a network error occurs while authenticating.
* @throws SaslException
* @throws NotConnectedException
*/
public void authenticate(String username, String host, String serviceName, String password) throws IOException, SaslException {
public void authenticate(String username, String host, String serviceName, String password) throws IOException, SaslException, NotConnectedException {
//Since we were not provided with a CallbackHandler, we will use our own with the given
//information
@ -153,15 +156,16 @@ public abstract class SASLMechanism implements CallbackHandler {
* @param cbh the CallbackHandler to obtain user information.
* @throws IOException If a network error occures while authenticating.
* @throws SaslException If a protocol error occurs or the user is not authenticated.
* @throws NotConnectedException
*/
public void authenticate(String host, CallbackHandler cbh) throws IOException, SaslException {
public void authenticate(String host, CallbackHandler cbh) throws IOException, SaslException, NotConnectedException {
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
}
protected void authenticate() throws IOException, SaslException {
protected void authenticate() throws IOException, SaslException, NotConnectedException {
String authenticationText = null;
if (sc.hasInitialResponse()) {
byte[] response = sc.evaluateChallenge(new byte[0]);
@ -178,8 +182,9 @@ public abstract class SASLMechanism implements CallbackHandler {
*
* @param challenge a base64 encoded string representing the challenge.
* @throws IOException if an exception sending the response occurs.
* @throws NotConnectedException
*/
public void challengeReceived(String challenge) throws IOException {
public void challengeReceived(String challenge) throws IOException, NotConnectedException {
byte response[];
if(challenge != null) {
response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));

View file

@ -23,6 +23,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionCreationListener;
@ -249,7 +250,12 @@ public class DummyConnection extends XMPPConnection {
// Deliver the incoming packet to listeners.
for (ListenerWrapper listenerWrapper : recvListeners.values()) {
listenerWrapper.notifyListener(packet);
try {
listenerWrapper.notifyListener(packet);
}
catch (NotConnectedException e) {
e.printStackTrace();
}
}
}
}

View file

@ -20,6 +20,7 @@ import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
@ -37,7 +38,12 @@ public class ThreadedDummyConnection extends DummyConnection {
@Override
public void sendPacket(Packet packet) {
super.sendPacket(packet);
try {
super.sendPacket(packet);
}
catch (NotConnectedException e) {
e.printStackTrace();
}
if (packet instanceof IQ && !timeout) {
timeout = false;