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