Cleanup XMPPTCPConnection, mostly exception handling

In initConnection, only initReaderAndWriter() throws IOException.

connectUsingConfiguration doesn't need to take an argument.

PacketReader.init does not throw a SmackException.

Use Async.go() in PacketWriter, just like it's already done in PacketReader.
This commit is contained in:
Florian Schmaus 2015-01-25 00:21:19 +01:00
parent d9c97fabfb
commit 30ec2bd072
2 changed files with 39 additions and 64 deletions

View File

@ -16,6 +16,7 @@
*/ */
package org.jivesoftware.smack.compression; package org.jivesoftware.smack.compression;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -47,9 +48,9 @@ public abstract class XMPPInputOutputStream {
public abstract boolean isSupported(); public abstract boolean isSupported();
public abstract InputStream getInputStream(InputStream inputStream) throws Exception; public abstract InputStream getInputStream(InputStream inputStream) throws IOException;
public abstract OutputStream getOutputStream(OutputStream outputStream) throws Exception; public abstract OutputStream getOutputStream(OutputStream outputStream) throws IOException;
public enum FlushMethod { public enum FlushMethod {
FULL_FLUSH, FULL_FLUSH,

View File

@ -516,7 +516,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
} }
private void connectUsingConfiguration(XMPPTCPConnectionConfiguration config) throws SmackException, IOException { private void connectUsingConfiguration() throws IOException, ConnectionException {
populateHostAddresses(); populateHostAddresses();
List<HostAddress> failedAddresses = new LinkedList<HostAddress>(); List<HostAddress> failedAddresses = new LinkedList<HostAddress>();
@ -574,70 +574,50 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
* @throws SmackException if the server failes to respond back or if there is anther error. * @throws SmackException if the server failes to respond back or if there is anther error.
* @throws IOException * @throws IOException
*/ */
private void initConnection() throws SmackException, IOException { private void initConnection() throws IOException {
boolean isFirstInitialization = packetReader == null || packetWriter == null; boolean isFirstInitialization = packetReader == null || packetWriter == null;
compressionHandler = null; compressionHandler = null;
// Set the reader and writer instance variables // Set the reader and writer instance variables
initReaderAndWriter(); initReaderAndWriter();
try { if (isFirstInitialization) {
if (isFirstInitialization) { packetWriter = new PacketWriter();
packetWriter = new PacketWriter(); packetReader = new PacketReader();
packetReader = new PacketReader();
// If debugging is enabled, we should start the thread that will listen for // If debugging is enabled, we should start the thread that will listen for
// all packets and then log them. // all packets and then log them.
if (config.isDebuggerEnabled()) { if (config.isDebuggerEnabled()) {
addAsyncPacketListener(debugger.getReaderListener(), null); addAsyncPacketListener(debugger.getReaderListener(), null);
if (debugger.getWriterListener() != null) { if (debugger.getWriterListener() != null) {
addPacketSendingListener(debugger.getWriterListener(), null); addPacketSendingListener(debugger.getWriterListener(), null);
}
} }
} }
// Start the packet writer. This will open a XMPP stream to the server
packetWriter.init();
// Start the packet reader. The startup() method will block until we
// get an opening stream packet back from server
packetReader.init();
if (isFirstInitialization) {
// Notify listeners that a new connection has been established
for (ConnectionCreationListener listener : getConnectionCreationListeners()) {
listener.connectionCreated(this);
}
}
} }
catch (SmackException ex) { // Start the packet writer. This will open a XMPP stream to the server
// An exception occurred in setting up the connection. Note that packetWriter.init();
// it's important here that we do an instant shutdown here, as this // Start the packet reader. The startup() method will block until we
// will not send a closing stream element, which will destroy // get an opening stream packet back from server
// Stream Management state on the server, which is not what we want. packetReader.init();
instantShutdown();
// Everything stopped. Now throw the exception. if (isFirstInitialization) {
throw ex; // Notify listeners that a new connection has been established
for (ConnectionCreationListener listener : getConnectionCreationListeners()) {
listener.connectionCreated(this);
}
} }
} }
private void initReaderAndWriter() throws IOException, SmackException { private void initReaderAndWriter() throws IOException {
try { InputStream is = socket.getInputStream();
InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream();
OutputStream os = socket.getOutputStream(); if (compressionHandler != null) {
if (compressionHandler != null) { is = compressionHandler.getInputStream(is);
is = compressionHandler.getInputStream(is); os = compressionHandler.getOutputStream(os);
os = compressionHandler.getOutputStream(os);
}
// OutputStreamWriter is already buffered, no need to wrap it into a BufferedWriter
writer = new OutputStreamWriter(os, "UTF-8");
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
}
catch (IOException e) {
throw e;
}
catch (Exception e) {
throw new SmackException(e);
} }
// OutputStreamWriter is already buffered, no need to wrap it into a BufferedWriter
writer = new OutputStreamWriter(os, "UTF-8");
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
// If debugging is enabled, we open a window and write out all network traffic. // If debugging is enabled, we open a window and write out all network traffic.
initDebugger(); initDebugger();
@ -817,7 +797,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
protected void connectInternal() throws SmackException, IOException, XMPPException { protected void connectInternal() throws SmackException, IOException, XMPPException {
throwAlreadyConnectedExceptionIfAppropriate(); throwAlreadyConnectedExceptionIfAppropriate();
// Establishes the connection, readers and writers // Establishes the connection, readers and writers
connectUsingConfiguration(config); connectUsingConfiguration();
socketClosed = false; socketClosed = false;
initConnection(); initConnection();
@ -920,10 +900,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
/** /**
* Initializes the reader in order to be used. The reader is initialized during the * Initializes the reader in order to be used. The reader is initialized during the
* first connection and when reconnecting due to an abruptly disconnection. * first connection and when reconnecting due to an abruptly disconnection.
*
* @throws SmackException if the parser could not be reset.
*/ */
void init() throws SmackException { void init() {
done = false; done = false;
Async.go(new Runnable() { Async.go(new Runnable() {
@ -1148,8 +1126,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
private final ArrayBlockingQueueWithShutdown<Element> queue = new ArrayBlockingQueueWithShutdown<Element>( private final ArrayBlockingQueueWithShutdown<Element> queue = new ArrayBlockingQueueWithShutdown<Element>(
QUEUE_SIZE, true); QUEUE_SIZE, true);
private Thread writerThread;
/** /**
* Needs to be protected for unit testing purposes. * Needs to be protected for unit testing purposes.
*/ */
@ -1179,14 +1155,12 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
queue.start(); queue.start();
writerThread = new Thread() { Async.go(new Runnable() {
@Override
public void run() { public void run() {
writePackets(); writePackets();
} }
}; }, "Smack Packet Writer (" + getConnectionCounter() + ")");
writerThread.setName("Smack Packet Writer (" + getConnectionCounter() + ")");
writerThread.setDaemon(true);
writerThread.start();
} }
private boolean done() { private boolean done() {