diff --git a/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java b/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java
index c20fe82..e682ea7 100644
--- a/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java
+++ b/ts3-client/core/src/main/java/com/ts3client/net/TeamspeakConnection.java
@@ -105,6 +105,11 @@ public final class TeamspeakConnection implements TS3Listener {
private ExecutorService eventExecutor;
private volatile boolean connected;
+ /**
+ * The connect in progress. A disconnect clears it and a newer connect replaces it, which
+ * tells a superseded attempt that is still failing not to clean up after itself.
+ */
+ private volatile Object connectAttempt;
private volatile int selfClientId = -1;
/** Package-private: read directly by {@link ConnectionStatsCollector}. */
volatile long connectedAtMs;
@@ -240,6 +245,8 @@ public final class TeamspeakConnection implements TS3Listener {
private void doConnect(String address, int port, String nickname, String password, LocalIdentity withIdentity,
String channel, String channelPassword) {
+ Object attempt = new Object();
+ connectAttempt = attempt;
try {
identity = withIdentity;
serverHost = address;
@@ -290,7 +297,7 @@ public final class TeamspeakConnection implements TS3Listener {
// A late packet dispatched after close() rejects on the shut-down
// command executor; harmless during teardown.
if (t instanceof java.util.concurrent.RejectedExecutionException) return;
- ui.onError("Network error: " + rootMessage(t));
+ ui.onError("Network error: " + messageChain(t));
});
applyClientVersion();
@@ -331,6 +338,9 @@ public final class TeamspeakConnection implements TS3Listener {
// Only captures if this connection holds the microphone.
applyMicrophoneState();
} catch (Exception e) {
+ // Whoever took over reports on their own; cleaning up here would tear down what a newer
+ // connect has set up in the meantime.
+ if (connectAttempt != attempt) return;
connected = false;
ui.onError("Connection failed: " + rootMessage(e) + versionHint(e));
safeCleanup();
@@ -505,6 +515,7 @@ public final class TeamspeakConnection implements TS3Listener {
* close) where the JVM must not exit before the leave notification is sent.
*/
public void disconnectBlocking(String reason) {
+ connectAttempt = null;
leaving = true;
try {
if (client != null) client.disconnect(reason);
@@ -1667,6 +1678,18 @@ public final class TeamspeakConnection implements TS3Listener {
return s == null ? "" : s;
}
+ /** Every message along the cause chain, outermost first: network errors are vague without context. */
+ private static String messageChain(Throwable t) {
+ StringBuilder chain = new StringBuilder();
+ for (Throwable c = t; c != null; c = c.getCause() == c ? null : c.getCause()) {
+ String m = c.getMessage();
+ if (m == null || chain.indexOf(m) >= 0) continue;
+ if (chain.length() > 0) chain.append(": ");
+ chain.append(m);
+ }
+ return chain.length() > 0 ? chain.toString() : t.getClass().getSimpleName();
+ }
+
private static String rootMessage(Throwable t) {
Throwable r = t;
while (r.getCause() != null && r.getCause() != r) r = r.getCause();
diff --git a/ts3-client/pom.xml b/ts3-client/pom.xml
index 6cdfc81..ddfda81 100644
--- a/ts3-client/pom.xml
+++ b/ts3-client/pom.xml
@@ -34,6 +34,12 @@
org.apache.maven.plugins
maven-surefire-plugin
${surefire.version}
+
+
+
+ ${project.build.directory}/test-home
+
+
diff --git a/ts3-client/swing/src/main/java/com/ts3client/Main.java b/ts3-client/swing/src/main/java/com/ts3client/Main.java
index 687b190..5562374 100644
--- a/ts3-client/swing/src/main/java/com/ts3client/Main.java
+++ b/ts3-client/swing/src/main/java/com/ts3client/Main.java
@@ -15,9 +15,10 @@ import javax.swing.SwingUtilities;
public final class Main {
public static void main(String[] args) {
- // ts3j is verbose by default; keep the console quiet unless debugging.
+ // ts3j is verbose by default; keep the console quiet unless asked for its protocol log
+ // (-Dts3j.debug=true, written to stderr).
try {
- com.github.manevolent.ts3j.util.Ts3Debugging.setEnabled(false);
+ com.github.manevolent.ts3j.util.Ts3Debugging.setEnabled(Boolean.getBoolean("ts3j.debug"));
} catch (Throwable ignored) {
}
diff --git a/ts3j b/ts3j
index 45cb8fd..2018c1c 160000
--- a/ts3j
+++ b/ts3j
@@ -1 +1 @@
-Subproject commit 45cb8fd5595d01e0d54f511e31757ff04617e128
+Subproject commit 2018c1c59347ec6655fb0a4d30ddf12f50c9a914