You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2019/12/20 19:08:58 UTC

[geode] 01/01: Revert "GEODE-7556: remove membership dependencies on geode-core exeptions (#4502)"

This is an automated email from the ASF dual-hosted git repository.

upthewaterspout pushed a commit to branch revert-4502-feature/GEODE-7556b
in repository https://gitbox.apache.org/repos/asf/geode.git

commit edb679e0a0392affa78e3d4c48e264b44dbf3f90
Author: Dan Smith <ds...@pivotal.io>
AuthorDate: Fri Dec 20 11:08:31 2019 -0800

    Revert "GEODE-7556: remove membership dependencies on geode-core exeptions (#4502)"
    
    This reverts commit a357e6d0d1e6eb6658e0e36900e3e1aaede77884.
---
 .../cache30/ReconnectWithCacheXMLDUnitTest.java    |  25 +--
 .../apache/geode/distributed/LocatorDUnitTest.java |  28 ++-
 .../ClusterDistributionManagerDUnitTest.java       |  31 +---
 .../internal/RestartOfMemberDistributedTest.java   |   2 -
 .../internal/cache/ConcurrentMapOpsDUnitTest.java  |  49 +-----
 .../MeterSubregistryReconnectDistributedTest.java  |   2 -
 .../LoggingWithReconnectDistributedTest.java       |   2 -
 .../internal/membership/MembershipJUnitTest.java   |   7 +-
 .../membership/gms/GMSMembershipJUnitTest.java     |   4 +-
 .../gms/fd/GMSHealthMonitorJUnitTest.java          |   3 +-
 .../gms/locator/GMSLocatorIntegrationTest.java     |   3 +-
 .../locator/GMSLocatorRecoveryIntegrationTest.java |   3 +-
 .../gms/membership/GMSJoinLeaveJUnitTest.java      |  27 ++-
 .../gms/messenger/JGroupsMessengerJUnitTest.java   |  87 ++++-----
 .../internal/ClusterDistributionManager.java       | 125 +++----------
 .../geode/distributed/internal/Distribution.java   |   9 +-
 .../distributed/internal/DistributionImpl.java     | 142 +++++----------
 .../distributed/internal/DistributionManager.java  |  14 --
 .../internal/LonerDistributionManager.java         |  10 --
 .../distributed/internal/direct/DirectChannel.java |   4 +-
 .../membership/adapter/GMSLocatorAdapter.java      |  14 +-
 .../internal/membership/gms/GMSMembership.java     | 196 ++++++++++++++++-----
 .../internal/membership/gms/GMSUtil.java           |  16 +-
 .../membership/gms/MembershipBuilderImpl.java      |  21 ++-
 .../internal/membership/gms/Services.java          |  33 ++--
 .../gms/api/MemberDisconnectedException.java       |  30 ----
 .../membership/gms/api/MemberStartupException.java |  35 ----
 .../internal/membership/gms/api/Membership.java    |  23 ++-
 .../membership/gms/api/MembershipBuilder.java      |   2 +-
 .../gms/api/MembershipClosedException.java         |  34 ----
 .../gms/api/MembershipConfigurationException.java  |  37 ----
 .../gms/api}/MembershipTestHook.java               |   2 +-
 .../membership/gms/api/MessageListener.java        |   2 +-
 .../membership/gms/fd/GMSHealthMonitor.java        |  39 ++--
 .../membership/gms/interfaces/JoinLeave.java       |   5 +-
 .../membership/gms/interfaces/Manager.java         |   3 +-
 .../membership/gms/interfaces/MessageHandler.java  |   4 +-
 .../membership/gms/interfaces/Messenger.java       |   3 +-
 .../membership/gms/interfaces/Service.java         |   6 +-
 .../membership/gms/locator/GMSLocator.java         |  15 +-
 .../membership/gms/membership/GMSJoinLeave.java    |  45 ++---
 .../membership/gms/messenger/GMSQuorumChecker.java |   4 +-
 .../membership/gms/messenger/JGroupsMessenger.java | 113 ++++++------
 .../apache/geode/internal/net/SocketCreator.java   |  70 ++++----
 .../org/apache/geode/internal/tcp/Connection.java  |   6 +-
 .../tcp}/MemberShunnedException.java               |   6 +-
 .../org/apache/geode/internal/tcp/TCPConduit.java  |   4 +-
 .../sanctioned-geode-core-serializables.txt        |   6 +-
 .../distributed/internal/DistributionTest.java     |   3 +-
 .../MembershipDependenciesJUnitTest.java           |  11 ++
 .../internal/membership/gms/GMSUtilTest.java       |  18 +-
 .../membership/gms/MembershipManagerHelper.java    |   6 +-
 52 files changed, 546 insertions(+), 843 deletions(-)

diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithCacheXMLDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithCacheXMLDUnitTest.java
index 36a0a5b..5502d9a 100755
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithCacheXMLDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ReconnectWithCacheXMLDUnitTest.java
@@ -14,14 +14,11 @@
  */
 package org.apache.geode.cache30;
 
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
-import static org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY;
 import static org.apache.geode.internal.Assert.assertTrue;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.apache.geode.test.util.ResourceUtils.createTempFileFromResource;
 import static org.junit.Assert.assertEquals;
 
-import java.io.File;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -32,15 +29,12 @@ import org.junit.experimental.categories.Category;
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.distributed.ConfigurationProperties;
-import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.ServerLauncherParameters;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.internal.AvailablePortHelper;
-import org.apache.geode.test.dunit.Invoke;
-import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
 import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
 import org.apache.geode.test.junit.categories.ClientServerTest;
@@ -61,22 +55,10 @@ public class ReconnectWithCacheXMLDUnitTest extends JUnit4CacheTestCase {
   @Rule
   public DistributedRestoreSystemProperties restoreSystemProperties =
       new DistributedRestoreSystemProperties();
-  private int locatorPort;
 
   @Override
   public final void postSetUp() {
     oldPropertySetting = System.setProperty(xmlProperty, "true");
-    // stress testing needs this so that join attempts don't give up too soon
-    Invoke.invokeInEveryVM(() -> System.setProperty("p2p.joinTimeout", "120000"));
-    // reconnect tests should create their own locator so as to not impact other tests
-    VM locatorVM = VM.getVM(0);
-    final int port = locatorVM.invoke(() -> {
-      System.setProperty(BYPASS_DISCOVERY_PROPERTY, "true");
-      System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "member-weight", "100");
-      return Locator.startLocatorAndDS(0, new File(""), new Properties()).getPort();
-    });
-    locatorPort = port;
-
   }
 
   @Override
@@ -86,7 +68,6 @@ public class ReconnectWithCacheXMLDUnitTest extends JUnit4CacheTestCase {
     } else {
       System.setProperty(xmlProperty, oldPropertySetting);
     }
-    disconnectAllFromDS();
   }
 
   @Override
@@ -98,9 +79,7 @@ public class ReconnectWithCacheXMLDUnitTest extends JUnit4CacheTestCase {
     result.setProperty(ConfigurationProperties.CACHE_XML_FILE, fileName);
     result.setProperty(ConfigurationProperties.ENABLE_NETWORK_PARTITION_DETECTION, "true");
     result.setProperty(ConfigurationProperties.DISABLE_AUTO_RECONNECT, "false");
-    result.setProperty(ConfigurationProperties.MAX_WAIT_TIME_RECONNECT, "3000");
-    result.setProperty(ConfigurationProperties.MEMBER_TIMEOUT, "2000");
-    result.put(LOCATORS, "localhost[" + locatorPort + "]");
+    result.setProperty(ConfigurationProperties.MAX_WAIT_TIME_RECONNECT, "2000");
     return result;
   }
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/distributed/LocatorDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/distributed/LocatorDUnitTest.java
index 94acffe..0725cc1 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/distributed/LocatorDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/distributed/LocatorDUnitTest.java
@@ -89,17 +89,14 @@ import org.apache.geode.distributed.internal.HighPriorityAckedMessage;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.distributed.internal.MembershipListener;
-import org.apache.geode.distributed.internal.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
 import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.tcp.Connection;
 import org.apache.geode.logging.internal.log4j.api.LogService;
-import org.apache.geode.test.awaitility.GeodeAwaitility;
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.DUnitBlackboard;
 import org.apache.geode.test.dunit.DistributedTestUtils;
@@ -166,8 +163,6 @@ public class LocatorDUnitTest implements Serializable {
     port3 = ports[2];
     port4 = ports[3];
     Invoke.invokeInEveryVM(() -> deleteLocatorStateFile(port1, port2, port3, port4));
-    addIgnoredException(MemberDisconnectedException.class); // ignore this suspect string
-    addIgnoredException(MembershipConfigurationException.class); // ignore this suspect string
   }
 
   @After
@@ -770,7 +765,7 @@ public class LocatorDUnitTest implements Serializable {
         addIgnoredException(ForcedDisconnectException.class);
 
         hook = new TestHook();
-        MembershipManagerHelper.addTestHook(system, hook);
+        MembershipManagerHelper.getDistribution(system).registerTestHook(hook);
         try {
           MembershipManagerHelper.crashDistributedSystem(system);
         } finally {
@@ -798,6 +793,8 @@ public class LocatorDUnitTest implements Serializable {
 
     vm2.invokeAsync(crashSystem);
 
+    Wait.pause(1000); // 4 x the member-timeout
+
     // request member removal for first peer from second peer.
     vm2.invoke(new SerializableRunnable("Request Member Removal") {
 
@@ -808,12 +805,11 @@ public class LocatorDUnitTest implements Serializable {
         // check for shutdown cause in Distribution. Following call should
         // throw DistributedSystemDisconnectedException which should have cause as
         // ForceDisconnectException.
-        await().until(() -> !mmgr.getMembership().isConnected());
         try (IgnoredException i = addIgnoredException("Membership: requesting removal of")) {
           mmgr.requestMemberRemoval((InternalDistributedMember) mem1, "test reasons");
           fail("It should have thrown exception in requestMemberRemoval");
         } catch (DistributedSystemDisconnectedException e) {
-          // expected
+          assertThat(e).hasRootCauseInstanceOf(ForcedDisconnectException.class);
         } finally {
           hook.reset();
         }
@@ -1310,15 +1306,13 @@ public class LocatorDUnitTest implements Serializable {
     vm2.invoke("waitUntilLocatorBecomesCoordinator", this::waitUntilLocatorBecomesCoordinator);
 
     if (vm1.invoke(() -> system.getDistributedMember().equals(getView().getCreator()))) {
-      vm2.invoke(() -> {
-        GeodeAwaitility.await()
-            .until(() -> !system.getDistributedMember().equals(getView().getCreator()));
-      });
+      assertFalse(
+          vm2.invoke("Checking ViewCreator",
+              () -> system.getDistributedMember().equals(getView().getCreator())));
     } else {
-      vm2.invoke(() -> {
-        GeodeAwaitility.await()
-            .until(() -> system.getDistributedMember().equals(getView().getCreator()));
-      });
+      assertTrue(
+          vm2.invoke("Checking ViewCreator",
+              () -> system.getDistributedMember().equals(getView().getCreator())));
     }
   }
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
index ea78eab..5009f55 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/ClusterDistributionManagerDUnitTest.java
@@ -20,7 +20,6 @@ import static org.apache.geode.distributed.ConfigurationProperties.BIND_ADDRESS;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
 import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
-import static org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
 import static org.apache.geode.test.dunit.Invoke.invokeInEveryVM;
@@ -30,7 +29,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-import java.io.File;
 import java.net.InetAddress;
 import java.util.Properties;
 import java.util.concurrent.ExecutorService;
@@ -58,14 +56,10 @@ import org.apache.geode.cache.RegionEvent;
 import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.util.CacheListenerAdapter;
-import org.apache.geode.distributed.ConfigurationProperties;
-import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
 import org.apache.geode.logging.internal.log4j.api.LogService;
-import org.apache.geode.test.dunit.Invoke;
 import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.cache.CacheTestCase;
@@ -86,7 +80,6 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
 
   private transient ExecutorService executorService;
 
-  private VM locatorvm;
   private VM vm1;
 
   @Rule
@@ -95,28 +88,11 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
 
   @Rule
   public SharedErrorCollector errorCollector = new SharedErrorCollector();
-  private int locatorPort;
 
   @Before
   public void setUp() {
     executorService = Executors.newSingleThreadExecutor();
-
-    locatorvm = VM.getVM(0);
     vm1 = VM.getVM(1);
-    Invoke.invokeInEveryVM(() -> System.setProperty("p2p.joinTimeout", "120000"));
-    final int port = locatorvm.invoke(() -> {
-      System.setProperty(BYPASS_DISCOVERY_PROPERTY, "true");
-      return Locator.startLocatorAndDS(0, new File(""), new Properties()).getPort();
-    });
-    vm1.invoke(() -> locatorPort = port);
-    locatorPort = port;
-  }
-
-  @Override
-  public Properties getDistributedSystemProperties() {
-    Properties result = super.getDistributedSystemProperties();
-    result.put(ConfigurationProperties.LOCATORS, "localhost[" + locatorPort + "]");
-    return result;
   }
 
   @After
@@ -261,7 +237,6 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
   @Test
   public void testKickOutSickMember() {
     addIgnoredException("10 seconds have elapsed while waiting");
-    addIgnoredException(MemberDisconnectedException.class);
 
     // in order to set a small ack-wait-threshold, we have to remove the
     // system property established by the dunit harness
@@ -346,7 +321,7 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
    */
   @Test
   public void testWaitForViewInstallation() {
-    InternalDistributedSystem system = getSystem();
+    InternalDistributedSystem system = getSystem(new Properties());
     ClusterDistributionManager dm = (ClusterDistributionManager) system.getDM();
     MembershipView<InternalDistributedMember> view = dm.getDistribution().getView();
 
@@ -362,8 +337,8 @@ public class ClusterDistributionManagerDUnitTest extends CacheTestCase {
 
     pause(2000);
 
-    vm1.invoke("create another member to initiate a new view", () -> {
-      getSystem();
+    VM.getVM(1).invoke("create another member to initiate a new view", () -> {
+      getSystem(new Properties());
     });
 
     await()
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/RestartOfMemberDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/RestartOfMemberDistributedTest.java
index a080a7c..e3339af 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/RestartOfMemberDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/distributed/internal/RestartOfMemberDistributedTest.java
@@ -27,7 +27,6 @@ import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.geode.ForcedDisconnectException;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 
 public class RestartOfMemberDistributedTest {
@@ -55,7 +54,6 @@ public class RestartOfMemberDistributedTest {
     clusterStartupRule.startServerVM(server2, properties, locatorPort1);
 
     addIgnoredException(ForcedDisconnectException.class.getName());
-    addIgnoredException(MemberDisconnectedException.class.getName());
     addIgnoredException("Possible loss of quorum due to the loss");
     addIgnoredException("Received invalid result from");
   }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ConcurrentMapOpsDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ConcurrentMapOpsDUnitTest.java
index 5751095..d38ffcd 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ConcurrentMapOpsDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ConcurrentMapOpsDUnitTest.java
@@ -15,9 +15,7 @@
 package org.apache.geode.internal.cache;
 
 import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_NETWORK_PARTITION_DETECTION;
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
-import static org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY;
 import static org.apache.geode.test.dunit.Assert.assertEquals;
 import static org.apache.geode.test.dunit.Assert.assertFalse;
 import static org.apache.geode.test.dunit.Assert.assertNotNull;
@@ -27,22 +25,17 @@ import static org.apache.geode.test.dunit.Assert.fail;
 
 import java.io.DataInput;
 import java.io.DataOutput;
-import java.io.File;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Ignore;
-import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.geode.DataSerializable;
 import org.apache.geode.Delta;
-import org.apache.geode.ForcedDisconnectException;
 import org.apache.geode.InvalidDeltaException;
 import org.apache.geode.cache.CacheListener;
 import org.apache.geode.cache.EntryEvent;
@@ -57,24 +50,19 @@ import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.cache.client.internal.DestroyOp;
 import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.cache.util.CacheListenerAdapter;
-import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.Distribution;
-import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.test.awaitility.GeodeAwaitility;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.IgnoredException;
-import org.apache.geode.test.dunit.Invoke;
 import org.apache.geode.test.dunit.LogWriterUtils;
 import org.apache.geode.test.dunit.SerializableCallable;
 import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.WaitCriterion;
 import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
-import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
 
 /**
  * tests for the concurrentMapOperations. there are more tests in ClientServerMiscDUnitTest
@@ -85,42 +73,15 @@ public class ConcurrentMapOpsDUnitTest extends JUnit4CacheTestCase {
   private static final String REP_REG_NAME = "repRegion";
   private static final String PR_REG_NAME = "prRegion";
   private static final int MAX_ENTRIES = 113;
-  private int locatorPort;
 
   enum OP {
     PUTIFABSENT, REPLACE, REMOVE
   }
 
-  @Rule
-  public DistributedRestoreSystemProperties restoreProperties =
-      new DistributedRestoreSystemProperties();
-
-  @Before
-  public void setup() {
-    // stress testing needs this so that join attempts don't give up too soon
-    Invoke.invokeInEveryVM(() -> System.setProperty("p2p.joinTimeout", "120000"));
-    VM locatorVM = VM.getVM(4);
-    final int port = locatorVM.invoke(() -> {
-      System.setProperty(BYPASS_DISCOVERY_PROPERTY, "true");
-      // set a big weight on the locator to prevent total shutdown when one server decides
-      // to kill the other server
-      System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "member-weight", "100");
-      return Locator.startLocatorAndDS(0, new File(""), new Properties()).getPort();
-    });
-    Invoke.invokeInEveryVM(() -> locatorPort = port);
-    locatorPort = port;
-  }
-
-  @After
-  public void teardown() {
-    VM.getVM(4).invoke(() -> disconnectFromDS());
-  }
-
   @Override
   public Properties getDistributedSystemProperties() {
     Properties result = super.getDistributedSystemProperties();
     result.put(ENABLE_NETWORK_PARTITION_DETECTION, "false");
-    result.put(LOCATORS, "localhost[" + locatorPort + "]");
     return result;
   }
 
@@ -1248,14 +1209,8 @@ public class ConcurrentMapOpsDUnitTest extends JUnit4CacheTestCase {
     Set<IgnoredException> exceptions = new HashSet<IgnoredException>();
     exceptions.add(IgnoredException.addIgnoredException("Membership: requesting removal", server1));
     exceptions.add(IgnoredException.addIgnoredException("Membership: requesting removal", server2));
-    exceptions.add(IgnoredException
-        .addIgnoredException(ForcedDisconnectException.class.getSimpleName(), server1));
-    exceptions.add(IgnoredException
-        .addIgnoredException(ForcedDisconnectException.class.getSimpleName(), server2));
-    exceptions.add(IgnoredException
-        .addIgnoredException(MemberDisconnectedException.class.getSimpleName(), server1));
-    exceptions.add(IgnoredException
-        .addIgnoredException(MemberDisconnectedException.class.getSimpleName(), server2));
+    exceptions.add(IgnoredException.addIgnoredException("ForcedDisconnect", server1));
+    exceptions.add(IgnoredException.addIgnoredException("ForcedDisconnect", server2));
 
     try {
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/metrics/MeterSubregistryReconnectDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/metrics/MeterSubregistryReconnectDistributedTest.java
index 8b616fd..704dc01 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/metrics/MeterSubregistryReconnectDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/metrics/MeterSubregistryReconnectDistributedTest.java
@@ -48,7 +48,6 @@ import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.LocatorLauncher;
 import org.apache.geode.distributed.internal.Distribution;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.rules.DistributedRule;
@@ -88,7 +87,6 @@ public class MeterSubregistryReconnectDistributedTest implements Serializable {
     otherServer.invoke(() -> createServer(OTHER_SERVER_NAME));
 
     addIgnoredException(ForcedDisconnectException.class);
-    addIgnoredException(MemberDisconnectedException.class);
     addIgnoredException("Possible loss of quorum");
   }
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
index 36b00a5..67f5638 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
@@ -48,7 +48,6 @@ import org.apache.geode.distributed.LocatorLauncher;
 import org.apache.geode.distributed.ServerLauncher;
 import org.apache.geode.distributed.internal.Distribution;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.rules.DistributedRule;
@@ -110,7 +109,6 @@ public class LoggingWithReconnectDistributedTest implements Serializable {
     server2VM.invoke(() -> createServer(server2Name, server2Dir, locatorPort));
 
     addIgnoredException(ForcedDisconnectException.class);
-    addIgnoredException(MemberDisconnectedException.class);
     addIgnoredException("Possible loss of quorum");
   }
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
index 5c87f6d..5027b51 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/MembershipJUnitTest.java
@@ -44,6 +44,7 @@ import org.junit.rules.TemporaryFolder;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import org.apache.geode.GemFireConfigException;
 import org.apache.geode.distributed.ConfigurationProperties;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
@@ -64,11 +65,9 @@ import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.LifecycleListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifierFactory;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipBuilder;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.JoinLeave;
@@ -257,7 +256,7 @@ public class MembershipJUnitTest {
 
   private Pair<Membership, MessageListener> createMembershipManager(
       final DistributionConfigImpl config,
-      final RemoteTransportConfig transport) throws MemberStartupException {
+      final RemoteTransportConfig transport) {
     final MembershipListener listener = mock(MembershipListener.class);
     final MessageListener messageListener = mock(MessageListener.class);
     final DMStats stats1 = mock(DMStats.class);
@@ -491,7 +490,7 @@ public class MembershipJUnitTest {
       joinLeave.init(services);
       throw new Error(
           "expected a GemFireConfigException to be thrown because no locators are configured");
-    } catch (MembershipConfigurationException e) {
+    } catch (GemFireConfigException e) {
       // expected
     }
   }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSMembershipJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSMembershipJUnitTest.java
index 44ff1f0..ed330c1 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSMembershipJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSMembershipJUnitTest.java
@@ -63,8 +63,6 @@ import org.apache.geode.distributed.internal.membership.gms.Services.Stopper;
 import org.apache.geode.distributed.internal.membership.gms.api.Authenticator;
 import org.apache.geode.distributed.internal.membership.gms.api.LifecycleListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
@@ -316,7 +314,7 @@ public class GMSMembershipJUnitTest {
   }
 
   @Test
-  public void noDispatchWhenSick() throws MemberShunnedException, MemberStartupException {
+  public void noDispatchWhenSick() {
     final DistributionMessage msg = mock(DistributionMessage.class);
     when(msg.dropMessageWhenMembershipIsPlayingDead()).thenReturn(true);
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java
index f19de75..b376ae0 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java
@@ -83,7 +83,6 @@ import org.apache.geode.distributed.internal.membership.gms.Services.Stopper;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberData;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberDataBuilder;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
 import org.apache.geode.distributed.internal.membership.gms.fd.GMSHealthMonitor.ClientSocketHandler;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.JoinLeave;
@@ -120,7 +119,7 @@ public class GMSHealthMonitorJUnitTest {
   private final int myAddressIndex = 3;
 
   @Before
-  public void initMocks() throws UnknownHostException, MemberStartupException {
+  public void initMocks() throws UnknownHostException {
     // ensure that Geode's serialization and version are initialized
     Version currentVersion = Version.CURRENT;
     InternalDataSerializer.getDSFIDSerializer();
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorIntegrationTest.java
index 4eefd71..aa16704 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorIntegrationTest.java
@@ -35,7 +35,6 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe
 import org.apache.geode.distributed.internal.membership.gms.GMSMembership;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.JoinLeave;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Messenger;
 import org.apache.geode.distributed.internal.tcpserver.TcpClient;
@@ -60,7 +59,7 @@ public class GMSLocatorIntegrationTest {
   private Messenger messenger;
 
   @Before
-  public void setUp() throws MembershipConfigurationException {
+  public void setUp() {
 
     SocketCreatorFactory.setDistributionConfig(new DistributionConfigImpl(new Properties()));
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorRecoveryIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorRecoveryIntegrationTest.java
index 5bb3539..091fca6 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorRecoveryIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocatorRecoveryIntegrationTest.java
@@ -42,6 +42,7 @@ import org.junit.rules.TemporaryFolder;
 import org.junit.rules.TestName;
 
 import org.apache.geode.DataSerializer;
+import org.apache.geode.InternalGemFireException;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.DMStats;
@@ -153,7 +154,7 @@ public class GMSLocatorRecoveryIntegrationTest {
     Throwable thrown = catchThrowable(() -> gmsLocator.recoverFromFile(stateFile));
 
     assertThat(thrown)
-        .isInstanceOf(IllegalStateException.class)
+        .isInstanceOf(InternalGemFireException.class)
         .hasMessageStartingWith("Unable to recover previous membership view from");
   }
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
index 85b77ea..9c24ec6 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
@@ -54,6 +54,7 @@ import org.junit.experimental.categories.Category;
 import org.mockito.internal.verification.Times;
 import org.mockito.verification.Timeout;
 
+import org.apache.geode.SystemConnectException;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.adapter.ServiceConfig;
@@ -65,7 +66,6 @@ import org.apache.geode.distributed.internal.membership.gms.Services.Stopper;
 import org.apache.geode.distributed.internal.membership.gms.api.Authenticator;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberDataBuilder;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.HealthMonitor;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Locator;
@@ -107,16 +107,15 @@ public class GMSJoinLeaveJUnitTest {
   private MemberIdentifier leaveMember = null;
   private TcpClient locatorClient;
 
-  public void initMocks() throws Exception {
+  public void initMocks() {
     initMocks(false);
   }
 
-  public void initMocks(boolean enableNetworkPartition) throws Exception {
+  public void initMocks(boolean enableNetworkPartition) {
     initMocks(enableNetworkPartition, false);
   }
 
-  public void initMocks(boolean enableNetworkPartition, boolean useTestGMSJoinLeave)
-      throws Exception {
+  public void initMocks(boolean enableNetworkPartition, boolean useTestGMSJoinLeave) {
     mockConfig = mock(ServiceConfig.class);
     when(mockConfig.getEnableNetworkPartitionDetection()).thenReturn(enableNetworkPartition);
     when(mockConfig.getSecurityUDPDHAlgo()).thenReturn("");
@@ -220,7 +219,7 @@ public class GMSJoinLeaveJUnitTest {
     // and will throw an exception when going to pause
     Thread.currentThread().interrupt();
     assertThatThrownBy(() -> gmsJoinLeave.findCoordinator())
-        .isInstanceOf(MemberStartupException.class)
+        .isInstanceOf(SystemConnectException.class)
         .hasMessageContaining("Interrupted while trying to contact locators");
     assertThat(Thread.currentThread().interrupted()).isTrue();
     verify(locatorClient, times(1)).requestToServer(isA(InetSocketAddress.class),
@@ -271,7 +270,7 @@ public class GMSJoinLeaveJUnitTest {
   }
 
   @Test
-  public void testProcessJoinMessageRejectOldMemberVersion() throws Exception {
+  public void testProcessJoinMessageRejectOldMemberVersion() throws IOException {
     initMocks();
 
     gmsJoinLeave.processMessage(new JoinRequestMessage(mockOldMember, mockOldMember, null, -1, 0));
@@ -293,7 +292,7 @@ public class GMSJoinLeaveJUnitTest {
 
 
   @Test
-  public void testProcessJoinMessageWithBadAuthentication() throws Exception {
+  public void testProcessJoinMessageWithBadAuthentication() throws IOException {
     initMocks();
     when(authenticator.authenticate(mockMembers[0], credentials))
         .thenThrow(new AuthenticationFailedException("we want to fail auth here"));
@@ -306,7 +305,7 @@ public class GMSJoinLeaveJUnitTest {
   }
 
   @Test
-  public void testProcessJoinMessageWithAuthenticationButNullCredentials() throws Exception {
+  public void testProcessJoinMessageWithAuthenticationButNullCredentials() throws IOException {
     initMocks();
     when(authenticator.authenticate(mockMembers[0], null))
         .thenThrow(new AuthenticationFailedException("we want to fail auth here"));
@@ -320,7 +319,7 @@ public class GMSJoinLeaveJUnitTest {
 
   // This test does not test the actual join process but rather that the join response gets logged
   @Test
-  public void testProcessJoinResponseIsRecorded() throws Exception {
+  public void testProcessJoinResponseIsRecorded() throws IOException {
     initMocks();
     when(authenticator.authenticate(mockMembers[0], null))
         .thenThrow(new AuthenticationFailedException("we want to fail auth here"));
@@ -437,7 +436,7 @@ public class GMSJoinLeaveJUnitTest {
 
 
   @Test
-  public void testRejectOlderView() throws Exception {
+  public void testRejectOlderView() throws IOException {
     initMocks();
     prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
 
@@ -453,7 +452,7 @@ public class GMSJoinLeaveJUnitTest {
   }
 
   @Test
-  public void testForceDisconnectedFromNewView() throws Exception {
+  public void testForceDisconnectedFromNewView() throws IOException {
     initMocks(true);// enabledNetworkPartition;
     Manager mockManager = mock(Manager.class);
     when(services.getManager()).thenReturn(mockManager);
@@ -840,7 +839,7 @@ public class GMSJoinLeaveJUnitTest {
   }
 
   @Test
-  public void testNetworkPartitionDetected() throws Exception {
+  public void testNetworkPartitionDetected() throws IOException {
     initMocks(true);
     prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
 
@@ -888,7 +887,7 @@ public class GMSJoinLeaveJUnitTest {
 
 
   @Test
-  public void testQuorumLossNotificationWithNetworkPartitionDetectionDisabled() throws Exception {
+  public void testQuorumLossNotificationWithNetworkPartitionDetectionDisabled() throws IOException {
     initMocks(false);
     prepareAndInstallView(mockMembers[0], createMemberList(mockMembers[0], gmsJoinLeaveMemberId));
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessengerJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessengerJUnitTest.java
index 9d66194..36aad0c 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessengerJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessengerJUnitTest.java
@@ -21,7 +21,6 @@ import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
 import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_TTL;
-import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -53,9 +52,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.TimeoutException;
 
 import org.jgroups.Address;
 import org.jgroups.Event;
@@ -69,8 +66,11 @@ import org.junit.After;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.ForcedDisconnectException;
+import org.apache.geode.GemFireIOException;
 import org.apache.geode.SerializationException;
 import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.internal.DistributionConfigImpl;
 import org.apache.geode.distributed.internal.DistributionStats;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
@@ -79,9 +79,7 @@ import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.MemberIdentifierFactoryImpl;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.Services.Stopper;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
 import org.apache.geode.distributed.internal.membership.gms.api.Message;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.HealthMonitor;
@@ -291,21 +289,27 @@ public class JGroupsMessengerJUnitTest {
       when(msg.getDSFID()).thenReturn((int) DataSerializableFixedID.HEARTBEAT_RESPONSE);
 
       // for code coverage we need to test with both a SerializationException and
-      // an IOException. The former is wrapped in a MembershipIOException while the
+      // an IOException. The former is wrapped in a GemfireIOException while the
       // latter is not
       doThrow(new SerializationException("")).when(msg).toData(any(DataOutput.class),
           any(SerializationContext.class));
-      Set<?> failures = messenger.send(msg);
-      assertThat(failures).isNotNull();
-      assertThat(failures).isNotEmpty();
+      try {
+        messenger.send(msg);
+        fail("expected a failure");
+      } catch (GemFireIOException e) {
+        // success
+      }
       if (enableMcast) {
         verify(msg, atLeastOnce()).registerProcessor();
       }
       doThrow(new IOException()).when(msg).toData(any(DataOutput.class),
           any(SerializationContext.class));
-      failures = messenger.send(msg);
-      assertThat(failures).isNotNull();
-      assertThat(failures).isNotEmpty();
+      try {
+        messenger.send(msg);
+        fail("expected a failure");
+      } catch (GemFireIOException e) {
+        // success
+      }
     }
   }
 
@@ -328,7 +332,7 @@ public class JGroupsMessengerJUnitTest {
         try {
           messenger.send(msg);
           fail("expected a failure");
-        } catch (MembershipClosedException e) {
+        } catch (DistributedSystemDisconnectedException e) {
           // success
         }
         verify(mockChannel).send(isA(org.jgroups.Message.class));
@@ -351,7 +355,7 @@ public class JGroupsMessengerJUnitTest {
         ex = new RuntimeException("");
         shutdownCause = new RuntimeException("shutdownCause");
       } else {
-        shutdownCause = new MemberDisconnectedException("");
+        shutdownCause = new ForcedDisconnectException("");
         ex = new RuntimeException("", shutdownCause);
       }
       doThrow(ex).when(mockChannel).send(any(org.jgroups.Message.class));
@@ -369,7 +373,7 @@ public class JGroupsMessengerJUnitTest {
         try {
           messenger.send(msg);
           fail("expected a failure");
-        } catch (MembershipClosedException e) {
+        } catch (DistributedSystemDisconnectedException e) {
           // the ultimate cause should be the shutdownCause returned
           // by Services.getShutdownCause()
           Throwable cause = e;
@@ -404,7 +408,7 @@ public class JGroupsMessengerJUnitTest {
         try {
           messenger.send(msg);
           fail("expected a failure");
-        } catch (MembershipClosedException e) {
+        } catch (DistributedSystemDisconnectedException e) {
           // success
         }
         verify(mockChannel, never()).send(isA(org.jgroups.Message.class));
@@ -426,8 +430,11 @@ public class JGroupsMessengerJUnitTest {
       when(msg.getMulticast()).thenReturn(enableMcast);
       when(msg.getDSFID()).thenReturn((int) DataSerializableFixedID.HEARTBEAT_RESPONSE);
       interceptor.collectMessages = true;
-      Set<?> failures = messenger.sendUnreliably(msg);
-      assertTrue(failures == null || failures.isEmpty());
+      try {
+        messenger.sendUnreliably(msg);
+      } catch (GemFireIOException e) {
+        fail("expected success");
+      }
       if (enableMcast) {
         verify(msg, atLeastOnce()).registerProcessor();
       }
@@ -587,12 +594,12 @@ public class JGroupsMessengerJUnitTest {
   public void testChannelStillConnectedAfterEmergencyCloseAfterForcedDisconnectWithAutoReconnect()
       throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doCallRealMethod().when(services).isShutdownDueToForcedDisconnect();
     doCallRealMethod().when(services).isAutoReconnectEnabled();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.emergencyClose();
     assertTrue(messenger.myChannel.isConnected());
@@ -602,12 +609,12 @@ public class JGroupsMessengerJUnitTest {
   public void testChannelStillConnectedAfterStopAfterForcedDisconnectWithAutoReconnect()
       throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doCallRealMethod().when(services).isShutdownDueToForcedDisconnect();
     doCallRealMethod().when(services).isAutoReconnectEnabled();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.stop();
     assertTrue(messenger.myChannel.isConnected());
@@ -616,13 +623,13 @@ public class JGroupsMessengerJUnitTest {
   @Test
   public void testChannelStillConnectedAfteremergencyWhileReconnectingDS() throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(true).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.emergencyClose();
     assertTrue(messenger.myChannel.isConnected());
@@ -632,13 +639,13 @@ public class JGroupsMessengerJUnitTest {
   @Test
   public void testChannelStillConnectedAfterStopWhileReconnectingDS() throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(true).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.stop();
     assertTrue(messenger.myChannel.isConnected());
@@ -647,13 +654,13 @@ public class JGroupsMessengerJUnitTest {
   @Test
   public void testChannelClosedOnEmergencyClose() throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.emergencyClose();
     assertFalse(messenger.myChannel.isConnected());
@@ -662,13 +669,13 @@ public class JGroupsMessengerJUnitTest {
   @Test
   public void testChannelClosedOnStop() throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.stop();
     assertFalse(messenger.myChannel.isConnected());
@@ -678,13 +685,13 @@ public class JGroupsMessengerJUnitTest {
   public void testChannelClosedAfterEmergencyCloseForcedDisconnectWithoutAutoReconnect()
       throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(true).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.emergencyClose();
     assertFalse(messenger.myChannel.isConnected());
@@ -694,13 +701,13 @@ public class JGroupsMessengerJUnitTest {
   public void testChannelStillConnectedStopAfterForcedDisconnectWithoutAutoReconnect()
       throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(true).when(services).isShutdownDueToForcedDisconnect();
     doReturn(false).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.stop();
     assertFalse(messenger.myChannel.isConnected());
@@ -710,13 +717,13 @@ public class JGroupsMessengerJUnitTest {
   public void testChannelClosedAfterEmergencyCloseNotForcedDisconnectWithAutoReconnect()
       throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(true).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.emergencyClose();
     assertFalse(messenger.myChannel.isConnected());
@@ -725,13 +732,13 @@ public class JGroupsMessengerJUnitTest {
   @Test
   public void testChannelStillConnectedStopNotForcedDisconnectWithAutoReconnect() throws Exception {
     initMocks(false);
-    doCallRealMethod().when(services).setShutdownCause(any(MemberDisconnectedException.class));
+    doCallRealMethod().when(services).setShutdownCause(any(ForcedDisconnectException.class));
     doCallRealMethod().when(services).getShutdownCause();
     doCallRealMethod().when(services).emergencyClose();
     doReturn(false).when(services).isShutdownDueToForcedDisconnect();
     doReturn(true).when(services).isAutoReconnectEnabled();
     doReturn(false).when(manager).isReconnectingDS();
-    services.setShutdownCause(new MemberDisconnectedException("Test Forced Disconnect"));
+    services.setShutdownCause(new ForcedDisconnectException("Test Forced Disconnect"));
     assertTrue(messenger.myChannel.isConnected());
     messenger.stop();
     assertFalse(messenger.myChannel.isConnected());
@@ -936,8 +943,8 @@ public class JGroupsMessengerJUnitTest {
       MemberIdentifier mbr = createAddress(1234);
       messenger.scheduledMcastSeqnos.put(mbr, new JGroupsMessenger.MessageTracker(30));
       messenger.waitForMessageState(mbr, state);
-      fail("expected a MembershipIOException to be thrown");
-    } catch (TimeoutException e) {
+      fail("expected a GemFireIOException to be thrown");
+    } catch (GemFireIOException e) {
       // pass
     }
   }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
index f8c1b1b..d823398 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
@@ -19,7 +19,6 @@ package org.apache.geode.distributed.internal;
 import java.io.NotSerializableException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -164,12 +163,6 @@ public class ClusterDistributionManager implements DistributionManager {
   private ClusterOperationExecutors executors;
 
   /**
-   * Membership failure listeners - for testing
-   */
-  private List<MembershipTestHook> membershipTestHooks;
-
-
-  /**
    * The <code>MembershipListener</code>s that are registered on this manager for ALL members.
    *
    * @since GemFire 5.7
@@ -2295,29 +2288,7 @@ public class ClusterDistributionManager implements DistributionManager {
     public void membershipFailure(String reason, Throwable t) {
       exceptionInThreads = true;
       rootCause = t;
-      if (rootCause != null && !(rootCause instanceof ForcedDisconnectException)) {
-        logger.info("cluster membership failed due to ", rootCause);
-        rootCause = new ForcedDisconnectException(rootCause.getMessage());
-      }
-      try {
-        if (membershipTestHooks != null) {
-          List<MembershipTestHook> l = membershipTestHooks;
-          for (final MembershipTestHook aL : l) {
-            MembershipTestHook dml = aL;
-            dml.beforeMembershipFailure(reason, rootCause);
-          }
-        }
-        getSystem().disconnect(reason, true);
-        if (membershipTestHooks != null) {
-          List<MembershipTestHook> l = membershipTestHooks;
-          for (final MembershipTestHook aL : l) {
-            MembershipTestHook dml = aL;
-            dml.afterMembershipFailure(reason, rootCause);
-          }
-        }
-      } catch (RuntimeException re) {
-        logger.warn("Exception caught while shutting down", re);
-      }
+      getSystem().disconnect(reason, true);
     }
 
     @Override
@@ -2326,63 +2297,39 @@ public class ClusterDistributionManager implements DistributionManager {
       // without holding the view lock. That can cause a race condition and
       // subsequent deadlock (#45566). Elder selection is now done when a view
       // is installed.
-      try {
-        dm.addNewMember(member);
-      } catch (VirtualMachineError err) {
-        // If this ever returns, rethrow the error. We're poisoned
-        // now, so don't let this thread continue.
-        throw err;
-      } catch (DistributedSystemDisconnectedException e) {
-        // don't log shutdown exceptions
-      } catch (Throwable t) {
-        logger.info(String.format("Membership: Fault while processing view addition of %s",
-            member),
-            t);
-      }
+      dm.addNewMember(member);
     }
 
     @Override
     public void memberDeparted(InternalDistributedMember theId, boolean crashed, String reason) {
-      try {
-        boolean wasAdmin = getAdminMemberSet().contains(theId);
-        if (wasAdmin) {
-          // Pretend we received an AdminConsoleDisconnectMessage from the console that
-          // is no longer in the JavaGroup view.
-          // It must have died without sending a ShutdownMessage.
-          // This fixes bug 28454.
-          AdminConsoleDisconnectMessage message = new AdminConsoleDisconnectMessage();
-          message.setSender(theId);
-          message.setCrashed(crashed);
-          message.setAlertListenerExpected(true);
-          message.setIgnoreAlertListenerRemovalFailure(true); // we don't know if it was a listener
-                                                              // so
-          // don't issue a warning
-          message.setRecipient(localAddress);
-          message.setReason(reason); // added for #37950
-          handleIncomingDMsg(message);
-        }
-        dm.handleManagerDeparture(theId, crashed, reason);
-      } catch (DistributedSystemDisconnectedException se) {
-        // let's not get huffy about it
-      }
+      boolean wasAdmin = getAdminMemberSet().contains(theId);
+      if (wasAdmin) {
+        // Pretend we received an AdminConsoleDisconnectMessage from the console that
+        // is no longer in the JavaGroup view.
+        // It must have died without sending a ShutdownMessage.
+        // This fixes bug 28454.
+        AdminConsoleDisconnectMessage message = new AdminConsoleDisconnectMessage();
+        message.setSender(theId);
+        message.setCrashed(crashed);
+        message.setAlertListenerExpected(true);
+        message.setIgnoreAlertListenerRemovalFailure(true); // we don't know if it was a listener so
+                                                            // don't issue a warning
+        message.setRecipient(localAddress);
+        message.setReason(reason); // added for #37950
+        handleIncomingDMsg(message);
+      }
+      dm.handleManagerDeparture(theId, crashed, reason);
     }
 
     @Override
     public void memberSuspect(InternalDistributedMember suspect,
         InternalDistributedMember whoSuspected, String reason) {
-      try {
-        dm.handleManagerSuspect(suspect, whoSuspected, reason);
-      } catch (DistributedSystemDisconnectedException se) {
-        // let's not get huffy about it
-      }
+      dm.handleManagerSuspect(suspect, whoSuspected, reason);
     }
 
     @Override
     public void viewInstalled(MembershipView view) {
-      try {
-        dm.handleViewInstalled(view);
-      } catch (DistributedSystemDisconnectedException se) {
-      }
+      dm.handleViewInstalled(view);
     }
 
     @Override
@@ -2709,36 +2656,6 @@ public class ClusterDistributionManager implements DistributionManager {
     return distributedSystemId;
   }
 
-  @Override
-  public void registerTestHook(MembershipTestHook mth) {
-    this.getDistribution().doWithViewLocked(() -> {
-      if (this.membershipTestHooks == null) {
-        this.membershipTestHooks = Collections.singletonList(mth);
-      } else {
-        List<MembershipTestHook> l = new ArrayList<>(this.membershipTestHooks);
-        l.add(mth);
-        this.membershipTestHooks = l;
-      }
-      return null;
-    });
-  }
-
-  @Override
-  public void unregisterTestHook(MembershipTestHook mth) {
-    this.getDistribution().doWithViewLocked(() -> {
-      if (this.membershipTestHooks != null) {
-        if (this.membershipTestHooks.size() == 1) {
-          this.membershipTestHooks = null;
-        } else {
-          List<MembershipTestHook> l = new ArrayList<>(this.membershipTestHooks);
-          l.remove(mth);
-          this.membershipTestHooks = l;
-        }
-      }
-      return null;
-    });
-  }
-
   /**
    * this causes the given InternalDistributedMembers to log thread dumps. If useNative is true we
    * attempt to use OSProcess native code for the dumps. This goes to stdout instead of the
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/Distribution.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/Distribution.java
index 830135a..03ba64c 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/Distribution.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/Distribution.java
@@ -25,6 +25,7 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.QuorumChecker;
 
@@ -47,7 +48,7 @@ public interface Distribution {
       DistributedMember member, boolean includeMulticast);
 
   void waitForMessageState(InternalDistributedMember member,
-      Map<String, Long> state) throws InterruptedException, java.util.concurrent.TimeoutException;
+      Map<String, Long> state) throws InterruptedException;
 
   boolean requestMemberRemoval(InternalDistributedMember member,
       String reason);
@@ -99,6 +100,12 @@ public interface Distribution {
 
   Throwable getShutdownCause();
 
+  void registerTestHook(
+      MembershipTestHook mth);
+
+  void unregisterTestHook(
+      MembershipTestHook mth);
+
   boolean addSurpriseMember(InternalDistributedMember mbr);
 
   void startupMessageFailed(InternalDistributedMember mbr,
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionImpl.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionImpl.java
index 9e1af37..09fd867 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionImpl.java
@@ -34,9 +34,6 @@ import java.util.function.Supplier;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.CancelException;
-import org.apache.geode.ForcedDisconnectException;
-import org.apache.geode.GemFireConfigException;
-import org.apache.geode.SystemConnectException;
 import org.apache.geode.SystemFailure;
 import org.apache.geode.ToDataException;
 import org.apache.geode.annotations.Immutable;
@@ -54,16 +51,12 @@ import org.apache.geode.distributed.internal.membership.gms.GMSMembership;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.LifecycleListener;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipBuilder;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipStatistics;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.Message;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
@@ -79,11 +72,8 @@ import org.apache.geode.internal.serialization.DeserializationContext;
 import org.apache.geode.internal.serialization.SerializationContext;
 import org.apache.geode.internal.serialization.Version;
 import org.apache.geode.internal.tcp.ConnectExceptions;
-import org.apache.geode.internal.tcp.ConnectionException;
 import org.apache.geode.internal.util.Breadcrumbs;
 import org.apache.geode.logging.internal.executors.LoggingThread;
-import org.apache.geode.security.AuthenticationRequiredException;
-import org.apache.geode.security.GemFireSecurityException;
 
 public class DistributionImpl implements Distribution {
   private static final Logger logger = Services.getLogger();
@@ -137,33 +127,24 @@ public class DistributionImpl implements Distribution {
     }
 
     memberTimeout = system.getConfig().getMemberTimeout();
-    try {
-      membership = MembershipBuilder.<InternalDistributedMember>newMembershipBuilder()
-          .setAuthenticator(
-              new GMSAuthenticator(system.getSecurityProperties(), system.getSecurityService(),
-                  system.getSecurityLogWriter(), system.getInternalLogWriter()))
-          .setStatistics(clusterDistributionManager.stats)
-          .setMessageListener(messageListener)
-          .setMembershipListener(listener)
-          .setConfig(new ServiceConfig(transport, system.getConfig()))
-          .setSerializer(InternalDataSerializer.getDSFIDSerializer())
-          .setLifecycleListener(new LifecycleListenerImpl(this))
-          .setMemberIDFactory(new ClusterDistributionManager.ClusterDistributionManagerIDFactory())
-          .setLocatorClient(new TcpClient(
-              asTcpSocketCreator(
-                  SocketCreatorFactory
-                      .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR)),
-              InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(),
-              InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()))
-          .create();
-    } catch (MembershipConfigurationException e) {
-      throw new GemFireConfigException(e.getMessage(), e.getCause());
-    } catch (GemFireSecurityException e) {
-      throw e;
-    } catch (RuntimeException e) {
-      Services.getLogger().error("Unexpected problem starting up membership services", e);
-      throw new SystemConnectException("Problem starting up membership services", e);
-    }
+    membership = MembershipBuilder.<InternalDistributedMember>newMembershipBuilder()
+        .setAuthenticator(
+            new GMSAuthenticator(system.getSecurityProperties(), system.getSecurityService(),
+                system.getSecurityLogWriter(), system.getInternalLogWriter()))
+        .setStatistics(clusterDistributionManager.stats)
+        .setMessageListener(messageListener)
+        .setMembershipListener(listener)
+        .setConfig(new ServiceConfig(transport, system.getConfig()))
+        .setSerializer(InternalDataSerializer.getDSFIDSerializer())
+        .setLifecycleListener(new LifecycleListenerImpl(this))
+        .setMemberIDFactory(new ClusterDistributionManager.ClusterDistributionManagerIDFactory())
+        .setLocatorClient(new TcpClient(
+            asTcpSocketCreator(
+                SocketCreatorFactory
+                    .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR)),
+            InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(),
+            InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()))
+        .create();
   }
 
   /**
@@ -195,28 +176,7 @@ public class DistributionImpl implements Distribution {
 
   @Override
   public void start() {
-    try {
-      membership.start();
-    } catch (ConnectionException e) {
-      throw new DistributionException(
-          "Unable to create membership manager",
-          e);
-    } catch (SecurityException e) {
-      String failReason = e.getMessage();
-      if (failReason.contains("Failed to find credentials")) {
-        throw new AuthenticationRequiredException(failReason);
-      }
-      throw new GemFireSecurityException(e.getMessage(),
-          e);
-    } catch (MembershipConfigurationException e) {
-      throw new GemFireConfigException(e.getMessage());
-    } catch (MemberStartupException e) {
-      throw new SystemConnectException(e.getMessage());
-    } catch (RuntimeException e) {
-      logger.error("Unexpected problem starting up membership services", e);
-      throw new SystemConnectException("Problem starting up membership services: " + e.getMessage()
-          + ".  Consult log file for more details");
-    }
+    membership.start();
   }
 
   @VisibleForTesting
@@ -267,7 +227,7 @@ public class DistributionImpl implements Distribution {
     Set<InternalDistributedMember> result;
     boolean allDestinations = msg.forAll();
 
-    checkCancelled();
+    membership.checkCancelled();
 
     membership.waitIfPlayingDead();
 
@@ -329,19 +289,6 @@ public class DistributionImpl implements Distribution {
   }
 
   /**
-   * This method catches membership exceptions that need to be translated into
-   * exceptions implementing CancelException in order to satisfy geode-core
-   * error handling.
-   */
-  private void checkCancelled() {
-    try {
-      membership.checkCancelled();
-    } catch (MembershipClosedException e) {
-      throw new DistributedSystemDisconnectedException(e.getMessage());
-    }
-  }
-
-  /**
    * Perform the grossness associated with sending a message over a DirectChannel
    *
    * @param destinations the list of destinations
@@ -376,16 +323,15 @@ public class DistributionImpl implements Distribution {
       }
 
       if (sentBytes == 0) {
-        checkCancelled();
+        membership.checkCancelled();
       }
-    } catch (MembershipClosedException e) {
-      throw new DistributedSystemDisconnectedException(e.getMessage(), e.getCause());
     } catch (DistributedSystemDisconnectedException ex) {
-      throw ex;
+      membership.checkCancelled();
+      throw ex; // see bug 41416
     } catch (ConnectExceptions ex) {
       // Check if the connect exception is due to system shutting down.
       if (membership.shutdownInProgress()) {
-        checkCancelled();
+        membership.checkCancelled();
         throw new DistributedSystemDisconnectedException();
       }
 
@@ -445,7 +391,7 @@ public class DistributionImpl implements Distribution {
 
   @Override
   public void waitForMessageState(InternalDistributedMember member,
-      Map<String, Long> state) throws InterruptedException, TimeoutException {
+      Map<String, Long> state) throws InterruptedException {
     if (Thread.interrupted())
       throw new InterruptedException();
     DirectChannel dc = directChannel;
@@ -463,16 +409,7 @@ public class DistributionImpl implements Distribution {
 
   @Override
   public boolean requestMemberRemoval(InternalDistributedMember member, String reason) {
-    try {
-      return membership.requestMemberRemoval(member, reason);
-    } catch (MemberDisconnectedException | MembershipClosedException e) {
-      throw new DistributedSystemDisconnectedException("Distribution is closed");
-    } catch (RuntimeException e) {
-      if (!membership.isConnected()) {
-        throw new DistributedSystemDisconnectedException("Distribution is closed", e);
-      }
-      throw e;
-    }
+    return membership.requestMemberRemoval(member, reason);
   }
 
   @Override
@@ -588,6 +525,18 @@ public class DistributionImpl implements Distribution {
   }
 
   @Override
+  public void registerTestHook(
+      MembershipTestHook mth) {
+    membership.registerTestHook(mth);
+  }
+
+  @Override
+  public void unregisterTestHook(
+      MembershipTestHook mth) {
+    membership.unregisterTestHook(mth);
+  }
+
+  @Override
   public boolean addSurpriseMember(InternalDistributedMember mbr) {
     return membership.addSurpriseMember(mbr);
   }
@@ -882,8 +831,7 @@ public class DistributionImpl implements Distribution {
     }
 
     @Override
-    public void messageReceived(Message<InternalDistributedMember> msg)
-        throws MemberShunnedException {
+    public void messageReceived(Message<InternalDistributedMember> msg) {
       membership.processMessage(msg);
 
     }
@@ -951,15 +899,7 @@ public class DistributionImpl implements Distribution {
     }
 
     @Override
-    public boolean disconnect(Exception cause) {
-      Exception exception = cause;
-      // translate into a ForcedDisconnectException if necessary
-      if (cause instanceof MemberDisconnectedException) {
-        exception = new ForcedDisconnectException(cause.getMessage());
-        if (cause.getCause() != null) {
-          exception.initCause(cause.getCause());
-        }
-      }
+    public boolean disconnect(Exception exception) {
       return distribution.disconnectDirectChannel(exception);
     }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
index 1db7aad..dbb3c72 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
@@ -452,18 +452,4 @@ public interface DistributionManager extends ReplySender {
    * Returns the {@link AlertingService}.
    */
   AlertingService getAlertingService();
-
-  /**
-   * register a test hook for membership events
-   *
-   * @see MembershipTestHook
-   */
-  void registerTestHook(MembershipTestHook mth);
-
-  /**
-   * remove a test hook previously registered with the manager
-   */
-  void unregisterTestHook(MembershipTestHook mth);
-
-
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
index d9d181c..69077a4 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
@@ -1478,14 +1478,4 @@ public class LonerDistributionManager implements DistributionManager {
   public AlertingService getAlertingService() {
     return NullAlertingService.get();
   }
-
-  @Override
-  public void registerTestHook(MembershipTestHook mth) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void unregisterTestHook(MembershipTestHook mth) {
-    throw new UnsupportedOperationException();
-  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
index ed92af6..ffe7c30 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
@@ -45,7 +45,6 @@ import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.DistributionMessage;
 import org.apache.geode.distributed.internal.ReplyProcessor21;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
 import org.apache.geode.internal.cache.DirectReplyMessage;
@@ -55,6 +54,7 @@ import org.apache.geode.internal.tcp.BaseMsgStreamer;
 import org.apache.geode.internal.tcp.ConnectExceptions;
 import org.apache.geode.internal.tcp.Connection;
 import org.apache.geode.internal.tcp.ConnectionException;
+import org.apache.geode.internal.tcp.MemberShunnedException;
 import org.apache.geode.internal.tcp.MsgStreamer;
 import org.apache.geode.internal.tcp.TCPConduit;
 import org.apache.geode.internal.util.Breadcrumbs;
@@ -699,7 +699,7 @@ public class DirectChannel {
     }
   }
 
-  public void receive(DistributionMessage msg, int bytesRead) throws MemberShunnedException {
+  public void receive(DistributionMessage msg, int bytesRead) {
     if (disconnected) {
       return;
     }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSLocatorAdapter.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSLocatorAdapter.java
index c079ad3..31f1b2e 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSLocatorAdapter.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSLocatorAdapter.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.nio.file.Path;
 
-import org.apache.geode.GemFireConfigException;
 import org.apache.geode.cache.GemFireCache;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.Distribution;
@@ -31,7 +30,6 @@ import org.apache.geode.distributed.internal.RestartableTcpHandler;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.NetLocator;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Locator;
 import org.apache.geode.distributed.internal.membership.gms.locator.GMSLocator;
 import org.apache.geode.distributed.internal.tcpserver.TcpClient;
@@ -63,14 +61,10 @@ public class GMSLocatorAdapter implements RestartableTcpHandler, NetLocator {
                 .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR)),
         InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(),
         InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer());
-    try {
-      gmsLocator =
-          new GMSLocator<>(bindAddress, locatorString, usePreferredCoordinators,
-              networkPartitionDetectionEnabled,
-              locatorStats, securityUDPDHAlgo, workingDirectory, locatorClient);
-    } catch (MembershipConfigurationException e) {
-      throw new GemFireConfigException(e.getMessage());
-    }
+    gmsLocator =
+        new GMSLocator<>(bindAddress, locatorString, usePreferredCoordinators,
+            networkPartitionDetectionEnabled,
+            locatorStats, securityUDPDHAlgo, workingDirectory, locatorClient);
   }
 
   @Override
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSMembership.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSMembership.java
index fc39073..44865ce 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSMembership.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSMembership.java
@@ -32,7 +32,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -41,31 +40,36 @@ import java.util.stream.Collectors;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.CancelException;
+import org.apache.geode.ForcedDisconnectException;
 import org.apache.geode.GemFireConfigException;
+import org.apache.geode.InternalGemFireError;
+import org.apache.geode.SystemConnectException;
 import org.apache.geode.SystemFailure;
 import org.apache.geode.annotations.internal.MakeNotStatic;
+import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.DistributionException;
 import org.apache.geode.distributed.internal.StartupMessage;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.adapter.LocalViewMessage;
 import org.apache.geode.distributed.internal.membership.gms.api.LifecycleListener;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipListener;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.Message;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
 import org.apache.geode.distributed.internal.membership.gms.api.QuorumChecker;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Manager;
 import org.apache.geode.internal.serialization.Version;
+import org.apache.geode.internal.tcp.ConnectionException;
+import org.apache.geode.internal.tcp.MemberShunnedException;
 import org.apache.geode.logging.internal.executors.LoggingExecutors;
 import org.apache.geode.logging.internal.executors.LoggingThread;
+import org.apache.geode.security.GemFireSecurityException;
 
 public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID> {
   private static final Logger logger = Services.getLogger();
@@ -243,6 +247,11 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
   private final MessageListener<ID> messageListener;
 
   /**
+   * Membership failure listeners - for testing
+   */
+  private List<MembershipTestHook> membershipTestHooks;
+
+  /**
    * This is a representation of the local member (ourself)
    */
   private ID address = null; // new ID(-1);
@@ -458,7 +467,19 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
         logger.info("Membership: Processing addition <{}>", m);
 
-        listener.newMemberConnected(m);
+        try {
+          listener.newMemberConnected(m);
+        } catch (VirtualMachineError err) {
+          // If this ever returns, rethrow the error. We're poisoned
+          // now, so don't let this thread continue.
+          throw err;
+        } catch (DistributedSystemDisconnectedException e) {
+          // don't log shutdown exceptions
+        } catch (Throwable t) {
+          logger.info(String.format("Membership: Fault while processing view addition of %s",
+              m),
+              t);
+        }
       } // additions
 
       // look for departures
@@ -521,7 +542,10 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       // the view is complete - let's install it
       newlatestView.makeUnmodifiable();
       latestView = newlatestView;
-      listener.viewInstalled(latestView);
+      try {
+        listener.viewInstalled(latestView);
+      } catch (DistributedSystemDisconnectedException se) {
+      }
     } finally {
       latestViewWriteLock.unlock();
     }
@@ -556,8 +580,9 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
    * Joins the distributed system
    *
    * @throws GemFireConfigException - configuration error
+   * @throws SystemConnectException - problem joining
    */
-  private void join() throws MemberStartupException {
+  private void join() {
     services.setShutdownCause(null);
     services.getCancelCriterion().cancel(null);
 
@@ -570,7 +595,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
         boolean ok = services.getJoinLeave().join();
 
         if (!ok) {
-          throw new MembershipConfigurationException("Unable to join the distributed system.  "
+          throw new GemFireConfigException("Unable to join the distributed system.  "
               + "Operation either timed out, was stopped or Locator does not exist.");
         }
 
@@ -578,6 +603,16 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
         latestView = new MembershipView<>(initialView, initialView.getViewId());
         latestView.makeUnmodifiable();
         listener.viewInstalled(latestView);
+
+      } catch (RuntimeException ex) {
+        throw ex;
+      } catch (Exception ex) {
+        if (ex.getCause() != null && ex.getCause().getCause() instanceof SystemConnectException) {
+          throw (SystemConnectException) (ex.getCause().getCause());
+        }
+        throw new DistributionException(
+            "An Exception was thrown while attempting to join the distributed system.",
+            ex);
       } finally {
         this.isJoining = false;
       }
@@ -683,7 +718,11 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       return; // Explicit deletion, no upcall.
     }
 
-    listener.memberDeparted(dm, crashed, reason);
+    try {
+      listener.memberDeparted(dm, crashed, reason);
+    } catch (DistributedSystemDisconnectedException se) {
+      // let's not get huffy about it
+    }
   }
 
   /**
@@ -707,8 +746,13 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
   public void startupMessageFailed(ID mbr, String failureMessage) {
     // fix for bug #40666
     addShunnedMember(mbr);
-    listener.memberDeparted(mbr, true,
-        "failed to pass startup checks");
+    // fix for bug #41329, hang waiting for replies
+    try {
+      listener.memberDeparted(mbr, true,
+          "failed to pass startup checks");
+    } catch (DistributedSystemDisconnectedException se) {
+      // let's not get huffy about it
+    }
   }
 
 
@@ -752,7 +796,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
           try {
             requestMemberRemoval(member,
                 "this member is no longer in the view but is initiating connections");
-          } catch (MembershipClosedException | MemberDisconnectedException e) {
+          } catch (CancelException e) {
             // okay to ignore
           }
         }).start();
@@ -843,7 +887,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
    *
    * @param msg the message to process
    */
-  protected void handleOrDeferMessage(Message<ID> msg) throws MemberShunnedException {
+  protected void handleOrDeferMessage(Message<ID> msg) {
     if (msg.dropMessageWhenMembershipIsPlayingDead() && (beingSick || playingDead)) {
       return;
     }
@@ -885,7 +929,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
    *
    * @param msg the message
    */
-  protected void dispatchMessage(Message<ID> msg) throws MemberShunnedException {
+  protected void dispatchMessage(Message<ID> msg) {
     ID m = msg.getSender();
     boolean shunned = false;
 
@@ -984,11 +1028,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
           (MembershipView<InternalDistributedMember>) viewArg,
           (GMSMembership<InternalDistributedMember>) GMSMembership.this);
 
-      try {
-        messageListener.messageReceived((Message<ID>) v);
-      } catch (MemberShunnedException e) {
-        logger.error("View installation was blocked by a MemberShunnedException", e);
-      }
+      messageListener.messageReceived((Message<ID>) v);
     } finally {
       latestViewWriteLock.unlock();
     }
@@ -1012,7 +1052,11 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       ID suspect = gmsMemberToDMember(suspectInfo.suspectedMember);
       ID who = gmsMemberToDMember(suspectInfo.whoSuspected);
       this.suspectedMembers.put(suspect, Long.valueOf(System.currentTimeMillis()));
-      listener.memberSuspect(suspect, who, suspectInfo.reason);
+      try {
+        listener.memberSuspect(suspect, who, suspectInfo.reason);
+      } catch (DistributedSystemDisconnectedException se) {
+        // let's not get huffy about it
+      }
     } finally {
       latestViewWriteLock.unlock();
     }
@@ -1049,9 +1093,11 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       processView(o.gmsView.getViewId(), o.gmsView);
     } else if (o.isSurpriseConnect()) { // connect
       processSurpriseConnect(o.member);
-    } else {
-      throw new IllegalArgumentException("unknown startup event: " + o);
     }
+
+    else // sanity
+      throw new InternalGemFireError(
+          String.format("unknown startup event: %s", o));
   }
 
   /**
@@ -1203,7 +1249,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
   }
 
   @Override
-  public void processMessage(final Message<ID> msg) throws MemberShunnedException {
+  public void processMessage(final Message<ID> msg) {
     // notify failure detection that we've had contact from a member
     services.getHealthMonitor().contactedBy(msg.getSender());
     handleOrDeferMessage(msg);
@@ -1286,7 +1332,21 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
     if (e != null) {
       try {
+        if (membershipTestHooks != null) {
+          List<MembershipTestHook> l = membershipTestHooks;
+          for (final MembershipTestHook aL : l) {
+            MembershipTestHook dml = aL;
+            dml.beforeMembershipFailure(reason, e);
+          }
+        }
         listener.membershipFailure(reason, e);
+        if (membershipTestHooks != null) {
+          List<MembershipTestHook> l = membershipTestHooks;
+          for (final MembershipTestHook aL : l) {
+            MembershipTestHook dml = aL;
+            dml.afterMembershipFailure(reason, e);
+          }
+        }
       } catch (RuntimeException re) {
         logger.warn("Exception caught while shutting down", re);
       }
@@ -1296,7 +1356,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
 
   @Override
-  public boolean requestMemberRemoval(ID mbr, String reason) throws MemberDisconnectedException {
+  public boolean requestMemberRemoval(ID mbr, String reason) {
     if (mbr.equals(this.address)) {
       return false;
     }
@@ -1305,13 +1365,13 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
     try {
       services.getJoinLeave().remove(mbr, reason);
     } catch (RuntimeException e) {
-      RuntimeException problem = e;
+      Throwable problem = e;
       if (services.getShutdownCause() != null) {
         Throwable cause = services.getShutdownCause();
         // If ForcedDisconnectException occurred then report it as actual
         // problem.
-        if ((cause instanceof MemberDisconnectedException)) {
-          throw (MemberDisconnectedException) cause;
+        if (cause instanceof ForcedDisconnectException) {
+          problem = cause;
         } else {
           Throwable ne = problem;
           while (ne.getCause() != null) {
@@ -1327,7 +1387,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       listener.saveConfig();
 
       listener.membershipFailure("Channel closed", problem);
-      throw new MembershipClosedException("Channel closed", problem);
+      throw new DistributedSystemDisconnectedException("Channel closed", problem);
     }
     return true;
   }
@@ -1404,11 +1464,11 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
   /**
    * Check to see if the membership system is being shutdown
    *
-   * @throws MembershipClosedException if the system is shutting down
+   * @throws DistributedSystemDisconnectedException if the system is shutting down
    */
-  public void checkCancelled() throws MembershipClosedException {
+  public void checkCancelled() {
     if (services.getCancelCriterion().isCancelInProgress()) {
-      throw new MembershipClosedException("Distributed System is shutting down",
+      throw new DistributedSystemDisconnectedException("Distributed System is shutting down",
           services.getCancelCriterion().generateCancelledException(services.getShutdownCause()));
     }
   }
@@ -1684,7 +1744,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
   @Override
   public void waitForMessageState(ID otherMember, Map<String, Long> state)
-      throws InterruptedException, TimeoutException {
+      throws InterruptedException {
     services.getMessenger().waitForMessageState(otherMember, state);
   }
 
@@ -1742,6 +1802,41 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
     return services.getShutdownCause();
   }
 
+  @Override
+  public void registerTestHook(MembershipTestHook mth) {
+    // lock for additions to avoid races during startup
+    latestViewWriteLock.lock();
+    try {
+      if (this.membershipTestHooks == null) {
+        this.membershipTestHooks = Collections.singletonList(mth);
+      } else {
+        List<MembershipTestHook> l = new ArrayList<>(this.membershipTestHooks);
+        l.add(mth);
+        this.membershipTestHooks = l;
+      }
+    } finally {
+      latestViewWriteLock.unlock();
+    }
+  }
+
+  @Override
+  public void unregisterTestHook(MembershipTestHook mth) {
+    latestViewWriteLock.lock();
+    try {
+      if (this.membershipTestHooks != null) {
+        if (this.membershipTestHooks.size() == 1) {
+          this.membershipTestHooks = null;
+        } else {
+          List<MembershipTestHook> l = new ArrayList<>(this.membershipTestHooks);
+          l.remove(mth);
+          this.membershipTestHooks = l;
+        }
+      }
+    } finally {
+      latestViewWriteLock.unlock();
+    }
+  }
+
   private volatile boolean beingSick;
   private volatile boolean playingDead;
 
@@ -1844,8 +1939,19 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
   }
 
   @Override
-  public void start() throws MemberStartupException {
-    services.start();
+  public void start() {
+    try {
+      services.start();
+    } catch (ConnectionException e) {
+      throw new DistributionException(
+          "Unable to create membership manager",
+          e);
+    } catch (GemFireConfigException | SystemConnectException | GemFireSecurityException e) {
+      throw e;
+    } catch (RuntimeException e) {
+      Services.getLogger().error("Unexpected problem starting up membership services", e);
+      throw new SystemConnectException("Problem starting up membership services", e);
+    }
   }
 
   @Override
@@ -1863,7 +1969,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
     @Override
     /* Service interface */
-    public void init(Services<ID> services) throws MembershipConfigurationException {
+    public void init(Services<ID> services) {
       GMSMembership.this.services = services;
 
       MembershipConfig config = services.getConfig();
@@ -1882,7 +1988,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
     /* Service interface */
     @Override
-    public void start() throws MemberStartupException {
+    public void start() {
       lifecycleListener.start(services.getMessenger().getMemberID());
 
     }
@@ -1963,12 +2069,12 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
 
     @Override
-    public void joinDistributedSystem() throws MemberStartupException {
+    public void joinDistributedSystem() {
       long startTime = System.currentTimeMillis();
 
       try {
         join();
-      } catch (MemberStartupException | RuntimeException e) {
+      } catch (RuntimeException e) {
         lifecycleListener.disconnect(e);
         throw e;
       }
@@ -2002,7 +2108,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
 
       setShutdown();
 
-      final Exception shutdownCause = new MemberDisconnectedException(reason);
+      final Exception shutdownCause = new ForcedDisconnectException(reason);
 
       // cache the exception so it can be appended to ShutdownExceptions
       services.setShutdownCause(shutdownCause);
@@ -2017,7 +2123,7 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
       if (this.isReconnectingDS()) {
         logger.info("Reconnecting system failed to connect");
         uncleanShutdown(reason,
-            new MemberDisconnectedException("reconnecting system failed to connect"));
+            new ForcedDisconnectException("reconnecting system failed to connect"));
         return;
       }
 
@@ -2067,14 +2173,14 @@ public class GMSMembership<ID extends MemberIdentifier> implements Membership<ID
           listener.quorumLost(
               gmsMemberCollectionToIDSet(failures),
               remaining);
-        } catch (Exception e) {
-          logger.info("Quorum-loss listener threw an exception", e);
+        } catch (CancelException e) {
+          // safe to ignore - a forced disconnect probably occurred
         }
       }
     }
 
     @Override
-    public void processMessage(Message<ID> msg) throws MemberShunnedException {
+    public void processMessage(Message<ID> msg) {
       // UDP messages received from surprise members will have partial IDs.
       // Attempt to replace these with full IDs from the Membership's view.
       if (msg.getSender().isPartial()) {
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
index 0708de3..0d8ded8 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
@@ -28,8 +28,8 @@ import java.util.StringTokenizer;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.GemFireConfigException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.membership.HostAddress;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.serialization.DeserializationContext;
@@ -47,8 +47,7 @@ public class GMSUtil {
    * @param bindAddress optional address to check for loopback compatibility
    * @return addresses of locators
    */
-  public static List<HostAddress> parseLocators(String locatorsString, String bindAddress)
-      throws MembershipConfigurationException {
+  public static List<HostAddress> parseLocators(String locatorsString, String bindAddress) {
     InetAddress addr = null;
 
     try {
@@ -86,8 +85,7 @@ public class GMSUtil {
    *
    * @see org.apache.geode.distributed.ConfigurationProperties#LOCATORS for format
    */
-  public static List<HostAddress> parseLocators(String locatorsString, InetAddress bindAddress)
-      throws MembershipConfigurationException {
+  public static List<HostAddress> parseLocators(String locatorsString, InetAddress bindAddress) {
     List<HostAddress> result = new ArrayList<>(2);
     Set<InetSocketAddress> inetAddresses = new HashSet<>();
     String host;
@@ -138,12 +136,12 @@ public class GMSUtil {
       final InetAddress locatorAddress = isa.getAddress();
 
       if (locatorAddress == null) {
-        throw new MembershipConfigurationException("This process is attempting to use a locator" +
+        throw new GemFireConfigException("This process is attempting to use a locator" +
             " at an unknown address or FQDN: " + host);
       }
 
       if (checkLoopback && isLoopback && !locatorAddress.isLoopbackAddress()) {
-        throw new MembershipConfigurationException(
+        throw new GemFireConfigException(
             "This process is attempting to join with a loopback address (" + bindAddress
                 + ") using a locator that does not have a local address (" + isa
                 + ").  On Unix this usually means that /etc/hosts is misconfigured.");
@@ -159,8 +157,8 @@ public class GMSUtil {
     return result;
   }
 
-  private static MembershipConfigurationException createBadPortException(final String str) {
-    return new MembershipConfigurationException("This process is attempting to use a locator" +
+  private static GemFireConfigException createBadPortException(final String str) {
+    return new GemFireConfigException("This process is attempting to use a locator" +
         " with a malformed port specification: " + str);
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipBuilderImpl.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipBuilderImpl.java
index 81626b4..061cb9f 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipBuilderImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipBuilderImpl.java
@@ -15,6 +15,9 @@
 package org.apache.geode.distributed.internal.membership.gms;
 
 
+import org.apache.geode.GemFireConfigException;
+import org.apache.geode.SystemConnectException;
+import org.apache.geode.distributed.internal.DistributionException;
 import org.apache.geode.distributed.internal.membership.gms.api.Authenticator;
 import org.apache.geode.distributed.internal.membership.gms.api.LifecycleListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
@@ -22,12 +25,13 @@ import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipBuilder;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipListener;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipStatistics;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
 import org.apache.geode.distributed.internal.tcpserver.TcpClient;
 import org.apache.geode.internal.serialization.DSFIDSerializer;
+import org.apache.geode.internal.tcp.ConnectionException;
+import org.apache.geode.security.GemFireSecurityException;
 
 public class MembershipBuilderImpl<ID extends MemberIdentifier> implements MembershipBuilder<ID> {
   private TcpClient locatorClient;
@@ -98,13 +102,24 @@ public class MembershipBuilderImpl<ID extends MemberIdentifier> implements Membe
   }
 
   @Override
-  public Membership<ID> create() throws MembershipConfigurationException {
+  public Membership<ID> create() {
     GMSMembership<ID> gmsMembership =
         new GMSMembership<>(membershipListener, messageListener, lifecycleListener);
     Services<ID> services =
         new Services<>(gmsMembership.getGMSManager(), statistics, authenticator,
             membershipConfig, serializer, memberFactory, locatorClient);
-    services.init();
+    try {
+      services.init();
+    } catch (ConnectionException e) {
+      throw new DistributionException(
+          "Unable to create membership manager",
+          e);
+    } catch (GemFireConfigException | SystemConnectException | GemFireSecurityException e) {
+      throw e;
+    } catch (RuntimeException e) {
+      Services.getLogger().error("Unexpected problem starting up membership services", e);
+      throw new SystemConnectException("Problem starting up membership services", e);
+    }
     return gmsMembership;
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/Services.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/Services.java
index 9da4c98..0926746 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/Services.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/Services.java
@@ -36,16 +36,15 @@ import java.util.Timer;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.CancelCriterion;
+import org.apache.geode.ForcedDisconnectException;
 import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.gms.api.Authenticator;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifierFactory;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipStatistics;
 import org.apache.geode.distributed.internal.membership.gms.fd.GMSHealthMonitor;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.HealthMonitor;
@@ -175,7 +174,7 @@ public class Services<ID extends MemberIdentifier> {
   /**
    * Initialize services - do this before invoking start()
    */
-  public void init() throws MembershipConfigurationException {
+  public void init() {
     this.messenger.init(this);
     this.manager.init(this);
     this.joinLeave.init(this);
@@ -186,7 +185,7 @@ public class Services<ID extends MemberIdentifier> {
    * Start services - this will start everything up and join the cluster.
    * Invoke init() before this method.
    */
-  public void start() throws MemberStartupException {
+  public void start() {
     boolean started = false;
     try {
       logger.info("Starting membership services");
@@ -367,7 +366,7 @@ public class Services<ID extends MemberIdentifier> {
   }
 
   public boolean isShutdownDueToForcedDisconnect() {
-    return this.shutdownCause instanceof MemberDisconnectedException;
+    return this.shutdownCause instanceof ForcedDisconnectException;
   }
 
   public boolean isAutoReconnectEnabled() {
@@ -378,44 +377,34 @@ public class Services<ID extends MemberIdentifier> {
     return this.serializer;
   }
 
-  public class Stopper {
+  public class Stopper extends CancelCriterion {
     volatile String reasonForStopping = null;
 
     public void cancel(String reason) {
       this.reasonForStopping = reason;
     }
 
+    @Override
     public String cancelInProgress() {
       if (Services.this.shutdownCause != null)
         return Services.this.shutdownCause.toString();
       return this.reasonForStopping;
     }
 
+    @Override
     public RuntimeException generateCancelledException(Throwable e) {
       String reason = cancelInProgress();
       if (reason == null) {
         return null;
       } else {
         if (e == null) {
-          return new MembershipClosedException(reason);
+          return new DistributedSystemDisconnectedException(reason);
         } else {
-          return new MembershipClosedException(reason, e);
+          return new DistributedSystemDisconnectedException(reason, e);
         }
       }
     }
 
-    public boolean isCancelInProgress() {
-      return cancelInProgress() != null;
-    }
-
-    public void checkCancelInProgress(Throwable e) {
-      String reason = cancelInProgress();
-      if (reason == null) {
-        return;
-      }
-      throw generateCancelledException(e);
-    }
-
   }
 
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberDisconnectedException.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberDisconnectedException.java
deleted file mode 100644
index 9e25f74..0000000
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberDisconnectedException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.distributed.internal.membership.gms.api;
-
-/**
- * MemberDisconnectedException indicates that we've been kicked out of the cluster.
- * Geode-core generally translates this into a ForcedDisconnectException, which is
- * part of its public API.
- */
-public class MemberDisconnectedException extends Exception {
-  private static final long serialVersionUID = -3649273301807236514L;
-
-  public MemberDisconnectedException() {}
-
-  public MemberDisconnectedException(String reason) {
-    super(reason);
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberStartupException.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberStartupException.java
deleted file mode 100644
index f9b30e2..0000000
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberStartupException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.distributed.internal.membership.gms.api;
-
-/**
- * MemberStartupException is thrown if there is a problem starting up membership
- * services or joining the cluster. A subclass of MemberStartupException,
- * MembershipConfigurationException, may also be thrown during startup and indicates a
- * problem with configuration parameters.
- */
-public class MemberStartupException extends Exception {
-  private static final long serialVersionUID = 6610743861046044144L;
-
-  public MemberStartupException() {}
-
-  public MemberStartupException(String reason) {
-    super(reason);
-  }
-
-  public MemberStartupException(String reason, Throwable cause) {
-    super(reason, cause);
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/Membership.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/Membership.java
index 6d65289..a2474a7 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/Membership.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/Membership.java
@@ -17,7 +17,6 @@ package org.apache.geode.distributed.internal.membership.gms.api;
 import java.io.NotSerializableException;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.TimeoutException;
 import java.util.function.Supplier;
 
 import org.apache.geode.SystemFailure;
@@ -72,12 +71,12 @@ public interface Membership<ID extends MemberIdentifier> {
    * @since GemFire 5.1
    */
   void waitForMessageState(ID member, Map<String, Long> state)
-      throws InterruptedException, TimeoutException;
+      throws InterruptedException;
 
   /**
    * Request the current membership coordinator to remove the given member
    */
-  boolean requestMemberRemoval(ID member, String reason) throws MemberDisconnectedException;
+  boolean requestMemberRemoval(ID member, String reason);
 
   /**
    * like memberExists() this checks to see if the given ID is in the current membership view. If it
@@ -236,6 +235,18 @@ public interface Membership<ID extends MemberIdentifier> {
   Throwable getShutdownCause();
 
   /**
+   * register a test hook for membership events
+   *
+   * @see MembershipTestHook
+   */
+  void registerTestHook(MembershipTestHook mth);
+
+  /**
+   * remove a test hook previously registered with the manager
+   */
+  void unregisterTestHook(MembershipTestHook mth);
+
+  /**
    * If this member is shunned, ensure that a warning is generated at least once.
    *
    * @param mbr the member that may be shunned
@@ -290,9 +301,9 @@ public interface Membership<ID extends MemberIdentifier> {
    * takes care of queueing up the message during startup and filtering out messages
    * from shunned members, before calling the message listener.
    */
-  void processMessage(Message<ID> msg) throws MemberShunnedException;
+  void processMessage(Message<ID> msg);
 
-  void checkCancelled() throws MembershipClosedException;
+  void checkCancelled();
 
   void waitIfPlayingDead();
 
@@ -307,7 +318,7 @@ public interface Membership<ID extends MemberIdentifier> {
    */
   boolean hasMember(ID member);
 
-  void start() throws MemberStartupException;
+  void start();
 
   void setCloseInProgress();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipBuilder.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipBuilder.java
index 3158644..3637979 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipBuilder.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipBuilder.java
@@ -43,7 +43,7 @@ public interface MembershipBuilder<ID extends MemberIdentifier> {
   MembershipBuilder<ID> setLocatorClient(final TcpClient tcpClient);
 
 
-  Membership<ID> create() throws MembershipConfigurationException;
+  Membership<ID> create();
 
   static <ID extends MemberIdentifier> MembershipBuilder<ID> newMembershipBuilder() {
     return new MembershipBuilderImpl<>();
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipClosedException.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipClosedException.java
deleted file mode 100644
index 2d46e95..0000000
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipClosedException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.distributed.internal.membership.gms.api;
-
-/**
- * MembershipClosedException is thrown if membership services are no longer
- * available. This exception may be thrown by any membership API and does
- * not appear in API interfaces.
- */
-public class MembershipClosedException extends RuntimeException {
-  private static final long serialVersionUID = 6112938405434046127L;
-
-  public MembershipClosedException() {}
-
-  public MembershipClosedException(String reason) {
-    super(reason);
-  }
-
-  public MembershipClosedException(String reason, Throwable cause) {
-    super(reason, cause);
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipConfigurationException.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipConfigurationException.java
deleted file mode 100644
index 2310da8..0000000
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipConfigurationException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.geode.distributed.internal.membership.gms.api;
-
-
-/**
- * MembershipConfigurationException may be thrown during startup and indicates a
- * problem with configuration parameters. MembershipConfigurationException is a
- * subclass of MemberStartupException, which may also be thrown during startup but
- * indicates a problem connecting to the cluster after membership configuration has
- * completed.
- */
-public class MembershipConfigurationException extends MemberStartupException {
-  private static final long serialVersionUID = 5633602142465129621L;
-
-  public MembershipConfigurationException() {}
-
-  public MembershipConfigurationException(String reason) {
-    super(reason);
-  }
-
-  public MembershipConfigurationException(String reason, Throwable cause) {
-    super(reason, cause);
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/MembershipTestHook.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipTestHook.java
similarity index 94%
rename from geode-core/src/main/java/org/apache/geode/distributed/internal/MembershipTestHook.java
rename to geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipTestHook.java
index 0d5d32c..b76facc 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/MembershipTestHook.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MembershipTestHook.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.distributed.internal;
+package org.apache.geode.distributed.internal.membership.gms.api;
 
 /**
  * Test hook for membership test development
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MessageListener.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MessageListener.java
index 9c250f9..8f8ee37 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MessageListener.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MessageListener.java
@@ -21,7 +21,7 @@ public interface MessageListener<ID extends MemberIdentifier> {
    *
    * @param o the message that should be processed.
    */
-  void messageReceived(Message<ID> o) throws MemberShunnedException;
+  void messageReceived(Message<ID> o);
 
 
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java
index 782515a..1f6fbd7 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java
@@ -51,15 +51,14 @@ import java.util.stream.Collectors;
 import org.apache.logging.log4j.Logger;
 import org.jgroups.util.UUID;
 
+import org.apache.geode.CancelException;
 import org.apache.geode.GemFireConfigException;
+import org.apache.geode.SystemConnectException;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipStatistics;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.HealthMonitor;
 import org.apache.geode.distributed.internal.membership.gms.messages.AbstractGMSMessage;
@@ -455,7 +454,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
       boolean pinged;
       try {
         pinged = GMSHealthMonitor.this.doCheckMember(mbr, true);
-      } catch (MembershipClosedException e) {
+      } catch (CancelException e) {
         return;
       }
 
@@ -670,7 +669,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
   }
 
   @Override
-  public void start() throws MemberStartupException {
+  public void start() {
     scheduler = LoggingExecutors.newScheduledThreadPool("Geode Failure Detection Scheduler", 1);
     checkExecutor = LoggingExecutors.newCachedThreadPool("Geode Failure Detection thread ", true);
     Monitor m = this.new Monitor(memberTimeout);
@@ -682,12 +681,18 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
   }
 
   ServerSocket createServerSocket(InetAddress socketAddress, int[] portRange) {
-    ServerSocket newSocket = SocketCreatorFactory
-        .getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
-        .createServerSocketUsingPortRange(socketAddress, 50/* backlog */, true/* isBindAddress */,
-            false/* useNIO */, 65536/* tcpBufferSize */, portRange, false);
-    socketPort = newSocket.getLocalPort();
-    return newSocket;
+    ServerSocket serverSocket;
+    try {
+      serverSocket = SocketCreatorFactory
+          .getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
+          .createServerSocketUsingPortRange(socketAddress, 50/* backlog */, true/* isBindAddress */,
+              false/* useNIO */, 65536/* tcpBufferSize */, portRange, false);
+      socketPort = serverSocket.getLocalPort();
+    } catch (IOException | SystemConnectException e) {
+      throw new GemFireConfigException(
+          "Unable to allocate a failure detection port in the membership-port range", e);
+    }
+    return serverSocket;
   }
 
   /**
@@ -784,7 +789,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
             }
             services.getMessenger().sendUnreliably(message);
             GMSHealthMonitor.this.stats.incHeartbeatsSent();
-          } catch (MembershipClosedException e) {
+          } catch (CancelException e) {
             return;
           }
         }
@@ -815,7 +820,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
             if (numSent >= NUM_HEARTBEATS) {
               break;
             }
-          } catch (MembershipClosedException e) {
+          } catch (CancelException e) {
             return;
           }
         }
@@ -920,7 +925,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
   }
 
   @Override
-  public void init(Services<ID> s) throws MembershipConfigurationException {
+  public void init(Services<ID> s) {
     isStopping = false;
     services = s;
     memberTimeout = s.getConfig().getMemberTimeout();
@@ -1184,7 +1189,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
           services.getMessenger().send(message);
           this.stats.incHeartbeatsSent();
           it.remove();
-        } catch (MembershipClosedException e) {
+        } catch (CancelException e) {
           return;
         }
       }
@@ -1295,7 +1300,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
       checkExecutor.execute(() -> {
         try {
           inlineCheckIfAvailable(initiator, cv, true, mbr, reason);
-        } catch (MembershipClosedException e) {
+        } catch (CancelException e) {
           // shutting down
         } catch (Exception e) {
           logger.info("Unexpected exception while verifying member", e);
@@ -1468,7 +1473,7 @@ public class GMSHealthMonitor<ID extends MemberIdentifier> implements HealthMoni
     try {
       failedRecipients = services.getMessenger().send(smm);
       this.stats.incSuspectsSent();
-    } catch (MembershipClosedException e) {
+    } catch (CancelException e) {
       return;
     }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/JoinLeave.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/JoinLeave.java
index 1e77151..7450fc4 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/JoinLeave.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/JoinLeave.java
@@ -16,15 +16,14 @@ package org.apache.geode.distributed.internal.membership.gms.interfaces;
 
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 
 public interface JoinLeave<ID extends MemberIdentifier> extends Service<ID> {
 
   /**
    * joins the distributed system and returns true if successful, false if not. Throws
-   * MemberStartupException and MemberConfigurationException
+   * SystemConnectException and GemFireConfigException
    */
-  boolean join() throws MemberStartupException;
+  boolean join();
 
   /**
    * leaves the distributed system. Should be invoked before stop()
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Manager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Manager.java
index ba4fe81..3ca5fd1 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Manager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Manager.java
@@ -19,7 +19,6 @@ import java.util.Collection;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
 import org.apache.geode.distributed.internal.membership.gms.api.Message;
 
 /**
@@ -32,7 +31,7 @@ public interface Manager<ID extends MemberIdentifier>
   /**
    * After all services have been started this is used to join the distributed system
    */
-  void joinDistributedSystem() throws MemberStartupException;
+  void joinDistributedSystem();
 
   /**
    * initiates a Forced Disconnect, shutting down the distributed system and closing the cache
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/MessageHandler.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/MessageHandler.java
index dcbf6c2..747dad1 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/MessageHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/MessageHandler.java
@@ -15,14 +15,12 @@
 package org.apache.geode.distributed.internal.membership.gms.interfaces;
 
 
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
-
 /**
  * MessageHandler processes a message received by Messenger. Handlers are registered with Messenger
  * to consume specific classes of message.
  */
 public interface MessageHandler<T> {
 
-  void processMessage(T m) throws MemberShunnedException;
+  void processMessage(T m);
 
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Messenger.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Messenger.java
index 4bc64bc..d6585a9 100755
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Messenger.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Messenger.java
@@ -16,7 +16,6 @@ package org.apache.geode.distributed.internal.membership.gms.interfaces;
 
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.TimeoutException;
 
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
@@ -84,7 +83,7 @@ public interface Messenger<ID extends MemberIdentifier> extends Service<ID> {
    * @param state the state of that member's outgoing messaging to this member
    */
   void waitForMessageState(ID member, Map<String, Long> state)
-      throws InterruptedException, TimeoutException;
+      throws InterruptedException;
 
   /**
    * Get the public key of member.
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Service.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Service.java
index 9f55b1e..1f53f4a8 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Service.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/interfaces/Service.java
@@ -17,21 +17,19 @@ package org.apache.geode.distributed.internal.membership.gms.interfaces;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 
 /**
  * Services in GMS all implement this interface
  *
  */
 public interface Service<ID extends MemberIdentifier> {
-  void init(Services<ID> s) throws MembershipConfigurationException;
+  void init(Services<ID> s);
 
   /**
    * called after all services have been initialized with init() and all services are available via
    * Services
    */
-  void start() throws MemberStartupException;
+  void start();
 
   /**
    * called after all servers have been started
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
index 8abcc8c..75bd001 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
@@ -37,6 +37,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.InternalGemFireException;
 import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.distributed.internal.LocatorStats;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembership;
@@ -45,7 +46,6 @@ import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.Locator;
 import org.apache.geode.distributed.internal.membership.gms.membership.HostAddress;
 import org.apache.geode.distributed.internal.membership.gms.messenger.GMSMemberWrapper;
@@ -98,8 +98,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
    */
   public GMSLocator(InetAddress bindAddress, String locatorString, boolean usePreferredCoordinators,
       boolean networkPartitionDetectionEnabled, LocatorStats locatorStats,
-      String securityUDPDHAlgo, Path workingDirectory, final TcpClient locatorClient)
-      throws MembershipConfigurationException {
+      String securityUDPDHAlgo, Path workingDirectory, final TcpClient locatorClient) {
     this.usePreferredCoordinators = usePreferredCoordinators;
     this.networkPartitionDetectionEnabled = networkPartitionDetectionEnabled;
     this.securityUDPDHAlgo = securityUDPDHAlgo;
@@ -161,7 +160,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
     return viewFile;
   }
 
-  public void init(String persistentFileIdentifier) {
+  public void init(String persistentFileIdentifier) throws InternalGemFireException {
     if (viewFile == null) {
       viewFile =
           workingDirectory.resolve("locator" + persistentFileIdentifier + "view.dat").toFile();
@@ -220,7 +219,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
     if (!findRequest.getDHAlgo().equals(securityUDPDHAlgo)) {
       return new FindCoordinatorResponse<>(
           "Rejecting findCoordinatorRequest, as member not configured same udp security("
-              + findRequest.getDHAlgo() + ") as locator (" + securityUDPDHAlgo + ")");
+              + findRequest.getDHAlgo() + " )as locator (" + securityUDPDHAlgo + ")");
     }
 
     if (services == null) {
@@ -383,7 +382,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
     }
   }
 
-  private void recover() {
+  private void recover() throws InternalGemFireException {
     if (!recoverFromOtherLocators()) {
       recoverFromFile(viewFile);
     }
@@ -417,7 +416,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
     return false;
   }
 
-  boolean recoverFromFile(File file) {
+  boolean recoverFromFile(File file) throws InternalGemFireException {
     if (!file.exists()) {
       logger.info("recovery file not found: {}", file.getAbsolutePath());
       return false;
@@ -470,7 +469,7 @@ public class GMSLocator<ID extends MemberIdentifier> implements Locator<ID> {
         logger.warn("Peer locator was unable to recover from or delete {}", file);
         viewFile = null;
       }
-      throw new IllegalStateException(message, e);
+      throw new InternalGemFireException(message, e);
     }
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 0d73e4e..c1dd5df 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -43,7 +43,10 @@ import java.util.concurrent.Future;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.GemFireConfigException;
+import org.apache.geode.SystemConnectException;
 import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.DistributionConfig;
@@ -51,10 +54,7 @@ import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.JoinLeave;
 import org.apache.geode.distributed.internal.membership.gms.locator.FindCoordinatorRequest;
 import org.apache.geode.distributed.internal.membership.gms.locator.FindCoordinatorResponse;
@@ -71,6 +71,8 @@ import org.apache.geode.distributed.internal.tcpserver.TcpClient;
 import org.apache.geode.internal.serialization.Version;
 import org.apache.geode.logging.internal.executors.LoggingExecutors;
 import org.apache.geode.logging.internal.executors.LoggingThread;
+import org.apache.geode.security.AuthenticationRequiredException;
+import org.apache.geode.security.GemFireSecurityException;
 
 /**
  * GMSJoinLeave handles membership communication with other processes in the distributed system. It
@@ -302,7 +304,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
    * @return true if successful, false if not
    */
   @Override
-  public boolean join() throws MemberStartupException {
+  public boolean join() {
 
     try {
       if (Boolean.getBoolean(BYPASS_DISCOVERY_PROPERTY)) {
@@ -395,10 +397,10 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
             + (System.currentTimeMillis() - startTime) + "ms");
       }
 
-      // to preserve old behavior we need to throw a MemberStartupException if
+      // to preserve old behavior we need to throw a SystemConnectException if
       // unable to contact any of the locators
       if (!this.isJoined && state.hasContactedAJoinedLocator) {
-        throw new MemberStartupException("Unable to join the distributed system in "
+        throw new SystemConnectException("Unable to join the distributed system in "
             + (System.currentTimeMillis() - startTime) + "ms");
       }
 
@@ -416,12 +418,12 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
 
   /**
    * send a join request and wait for a reply. Process the reply. This may throw a
-   * MemberStartupException or an exception from the authenticator, if present.
+   * SystemConnectException or an AuthenticationFailedException
    *
    * @return true if the attempt succeeded, false if it timed out
    */
   @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "WA_NOT_IN_LOOP")
-  boolean attemptToJoin() throws MemberStartupException {
+  boolean attemptToJoin() {
     SearchState<ID> state = searchState;
 
     // send a join request to the coordinator and wait for a response
@@ -460,9 +462,11 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
       if (failReason.contains("Rejecting the attempt of a member using an older version")
           || failReason.contains("15806")
           || failReason.contains("ForcedDisconnectException")) {
-        throw new MemberStartupException(failReason);
+        throw new SystemConnectException(failReason);
+      } else if (failReason.contains("Failed to find credentials")) {
+        throw new AuthenticationRequiredException(failReason);
       }
-      throw new SecurityException(failReason);
+      throw new GemFireSecurityException(failReason);
     }
 
     throw new RuntimeException("Join Request Failed with response " + response);
@@ -1106,7 +1110,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
    * This contacts the locators to find out who the current coordinator is. All locators are
    * contacted. If they don't agree then we choose the oldest coordinator and return it.
    */
-  boolean findCoordinator() throws MemberStartupException {
+  boolean findCoordinator() {
     SearchState<ID> state = searchState;
 
     assert this.localAddress != null;
@@ -1145,7 +1149,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
               (o instanceof FindCoordinatorResponse) ? (FindCoordinatorResponse<ID>) o : null;
           if (response != null) {
             if (response.getRejectionMessage() != null) {
-              throw new MembershipConfigurationException(response.getRejectionMessage());
+              throw new GemFireConfigException(response.getRejectionMessage());
             }
             setCoordinatorPublicKey(response);
             state.locatorsContacted++;
@@ -1191,7 +1195,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
             } catch (InterruptedException e) {
               Thread.currentThread().interrupt();
               services.getCancelCriterion().checkCancelInProgress(e);
-              throw new MemberStartupException("Interrupted while trying to contact locators");
+              throw new SystemConnectException("Interrupted while trying to contact locators");
             }
           }
         }
@@ -1676,7 +1680,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
   }
 
   @Override
-  public void start() throws MemberStartupException {}
+  public void start() {}
 
   @Override
   public void started() {}
@@ -1819,16 +1823,15 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
   }
 
   @Override
-  public void init(Services<ID> s) throws MembershipConfigurationException {
+  public void init(Services<ID> s) {
     this.services = s;
 
     MembershipConfig config = services.getConfig();
     if (config.getMcastPort() != 0 && StringUtils.isBlank(config.getLocators())
         && StringUtils.isBlank(config.getStartLocator())) {
-      throw new MembershipConfigurationException(
-          "Multicast cannot be configured for a non-distributed cache."
-              + "  Please configure the locator services for this cache using " + LOCATORS + " or "
-              + START_LOCATOR + ".");
+      throw new GemFireConfigException("Multicast cannot be configured for a non-distributed cache."
+          + "  Please configure the locator services for this cache using " + LOCATORS + " or "
+          + START_LOCATOR + ".");
     }
 
     services.getMessenger().addHandler(JoinRequestMessage.class, this::processMessage);
@@ -2184,7 +2187,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
           }
         } catch (InterruptedException e) {
           setShutdownFlag();
-        } catch (MembershipClosedException e) {
+        } catch (DistributedSystemDisconnectedException e) {
           setShutdownFlag();
         }
       } while (retry);
@@ -2319,7 +2322,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier> implements JoinLeave<ID>
               } catch (InterruptedException e2) {
                 setShutdownFlag();
               }
-            } catch (MembershipClosedException e) {
+            } catch (DistributedSystemDisconnectedException e) {
               setShutdownFlag();
             } catch (InterruptedException e) {
               logger.info("View Creator thread interrupted");
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/GMSQuorumChecker.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/GMSQuorumChecker.java
index e34dea7..a74ca65 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/GMSQuorumChecker.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/GMSQuorumChecker.java
@@ -81,7 +81,6 @@ public class GMSQuorumChecker<ID extends MemberIdentifier> implements QuorumChec
   }
 
 
-  @Override
   public synchronized boolean checkForQuorum(long timeout) throws InterruptedException {
     if (quorumAchieved) {
       return true;
@@ -99,7 +98,6 @@ public class GMSQuorumChecker<ID extends MemberIdentifier> implements QuorumChec
     return quorumAchieved;
   }
 
-  @Override
   public void close() {
     if (channel != null && !channel.isClosed()) {
       channel.close();
@@ -111,7 +109,7 @@ public class GMSQuorumChecker<ID extends MemberIdentifier> implements QuorumChec
     JGroupsMessenger.setChannelReceiver(channel, new QuorumCheckerReceiver());
   }
 
-  @Override
+
   public MembershipInformation getMembershipInfo() {
     return new MembershipInformationImpl(channel, messageQueue);
   }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
index f446bdf..19ed2eb 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
@@ -42,7 +42,6 @@ import java.util.Queue;
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
@@ -67,21 +66,23 @@ import org.jgroups.stack.IpAddress;
 import org.jgroups.util.Digest;
 import org.jgroups.util.UUID;
 
+import org.apache.geode.ForcedDisconnectException;
+import org.apache.geode.GemFireConfigException;
+import org.apache.geode.GemFireIOException;
+import org.apache.geode.InternalGemFireError;
+import org.apache.geode.InternalGemFireException;
+import org.apache.geode.SystemConnectException;
 import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.annotations.internal.MutableForTesting;
+import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.membership.gms.GMSMemberData;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
 import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
 import org.apache.geode.distributed.internal.membership.gms.Services;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberData;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberDisconnectedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MemberIdentifier;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberStartupException;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfig;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
 import org.apache.geode.distributed.internal.membership.gms.api.MembershipStatistics;
 import org.apache.geode.distributed.internal.membership.gms.api.Message;
 import org.apache.geode.distributed.internal.membership.gms.interfaces.HealthMonitor;
@@ -98,7 +99,7 @@ import org.apache.geode.internal.serialization.BufferDataOutputStream;
 import org.apache.geode.internal.serialization.StaticSerialization;
 import org.apache.geode.internal.serialization.Version;
 import org.apache.geode.internal.serialization.VersionedDataInputStream;
-
+import org.apache.geode.internal.tcp.MemberShunnedException;
 
 @SuppressWarnings("StatementWithEmptyBody")
 public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<ID> {
@@ -184,14 +185,14 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       receiver.setAccessible(true);
       receiver.set(channel, r);
     } catch (NoSuchFieldException | IllegalAccessException e) {
-      throw new IllegalStateException("unable to establish a JGroups receiver", e);
+      throw new InternalGemFireException("unable to establish a JGroups receiver", e);
     }
   }
 
   @Override
   @edu.umd.cs.findbugs.annotations.SuppressWarnings(
       value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
-  public void init(Services<ID> s) throws MembershipConfigurationException {
+  public void init(Services<ID> s) {
     this.services = s;
 
     MembershipConfig config = services.getConfig();
@@ -219,7 +220,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       is = ClassLoader.getSystemResourceAsStream(r);
     }
     if (is == null) {
-      throw new MembershipConfigurationException(
+      throw new GemFireConfigException(
           String.format("Cannot find %s", r));
     }
 
@@ -235,7 +236,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       br.close();
       properties = sb.toString();
     } catch (Exception ex) {
-      throw new MembershipConfigurationException(
+      throw new GemFireConfigException(
           "An Exception was thrown while reading JGroups config.",
           ex);
     }
@@ -279,7 +280,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       try {
         str = SocketCreator.getLocalHost().getHostAddress();
       } catch (UnknownHostException e) {
-        throw new MembershipConfigurationException(e.getMessage(), e);
+        throw new GemFireConfigException(e.getMessage(), e);
       }
     }
     properties = replaceStrings(properties, "BIND_ADDR_SETTING", "bind_addr=\"" + str + "\"");
@@ -310,7 +311,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
         this.encrypt = new GMSEncrypt<>(services, config.getSecurityUDPDHAlgo());
         logger.info("Initializing GMSEncrypt ");
       } catch (Exception e) {
-        throw new MembershipConfigurationException("problem initializing encryption protocol", e);
+        throw new GemFireConfigException("problem initializing encryption protocol", e);
       }
     }
   }
@@ -318,7 +319,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
   @Override
   @edu.umd.cs.findbugs.annotations.SuppressWarnings(
       value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
-  public void start() throws MemberStartupException {
+  public void start() {
     // create the configuration XML string for JGroups
     String properties = this.jgStackConfig;
 
@@ -360,7 +361,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
         myChannel = new JChannel(is);
       }
     } catch (Exception e) {
-      throw new MembershipConfigurationException("unable to create jgroups channel", e);
+      throw new GemFireConfigException("unable to create jgroups channel", e);
     }
 
     // give the stats to the jchannel statistics recorder
@@ -377,22 +378,18 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
 
     try {
       jgroupsReceiver = new JGroupsReceiver();
-      try {
-        setChannelReceiver(myChannel, jgroupsReceiver);
-      } catch (IllegalStateException e) {
-        throw new MemberStartupException("problem initializing JGroups", e);
-      }
+      setChannelReceiver(myChannel, jgroupsReceiver);
       if (!reconnecting) {
         myChannel.connect("AG"); // Apache Geode
       }
     } catch (Exception e) {
       myChannel.close();
-      throw new MemberStartupException("unable to create jgroups channel", e);
+      throw new SystemConnectException("unable to create jgroups channel", e);
     }
 
     if (JGroupsMessenger.THROW_EXCEPTION_ON_START_HOOK) {
       JGroupsMessenger.THROW_EXCEPTION_ON_START_HOOK = false;
-      throw new MemberStartupException("failing for test");
+      throw new SystemConnectException("failing for test");
     }
 
     establishLocalAddress();
@@ -517,7 +514,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
     }
   }
 
-  private void establishLocalAddress() throws MemberStartupException {
+  private void establishLocalAddress() {
     UUID logicalAddress = (UUID) myChannel.getAddress();
     logicalAddress = logicalAddress.copy();
 
@@ -534,7 +531,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
         ipaddr = (IpAddress) getAddress.invoke(udp, new Object[0]);
         this.jgAddress = new JGAddress(logicalAddress, ipaddr);
       } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
-        throw new MemberStartupException(
+        throw new InternalGemFireError(
             "Unable to configure JGroups channel for membership communications", e);
       }
     }
@@ -613,7 +610,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
 
   @Override
   public void waitForMessageState(ID sender, Map<String, Long> state)
-      throws InterruptedException, TimeoutException {
+      throws InterruptedException {
     Long seqno = state.get("JGroups.mcastState");
     if (seqno == null) {
       return;
@@ -652,7 +649,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
             Long.toString((warnTime - startTime) / 1000L), sender, received, seqno);
       }
       if (now >= quitTime) {
-        throw new TimeoutException("Multicast operations from " + sender
+        throw new GemFireIOException("Multicast operations from " + sender
             + " did not distribute within " + (now - startTime) + " milliseconds");
       }
       Thread.sleep(50);
@@ -682,7 +679,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
 
     if (!myChannel.isConnected()) {
       logger.info("JGroupsMessenger channel is closed - messaging is not possible");
-      throw new MembershipClosedException("Distributed System is shutting down");
+      throw new DistributedSystemDisconnectedException("Distributed System is shutting down");
     }
 
     filterOutgoingMessage(msg);
@@ -704,18 +701,12 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
 
     JGAddress local = this.jgAddress;
 
-    Set<ID> failedRecipients = new HashSet<>();
     if (useMcast) {
+
       long startSer = theStats.startMsgSerialization();
-      org.jgroups.Message jmsg;
-      try {
-        jmsg =
-            createJGMessage(msg, local, null, Version.getCurrentVersion().ordinal());
-      } catch (IOException e) {
-        return new HashSet<>(msg.getRecipients());
-      } finally {
-        theStats.endMsgSerialization(startSer);
-      }
+      org.jgroups.Message jmsg =
+          createJGMessage(msg, local, null, Version.getCurrentVersion().ordinal());
+      theStats.endMsgSerialization(startSer);
 
       Exception problem;
       try {
@@ -729,7 +720,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       } catch (Exception e) {
         logger.debug("caught unexpected exception", e);
         Throwable cause = e.getCause();
-        if (cause instanceof MemberDisconnectedException) {
+        if (cause instanceof ForcedDisconnectException) {
           problem = (Exception) cause;
         } else {
           problem = e;
@@ -738,7 +729,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
           Throwable shutdownCause = services.getShutdownCause();
           // If ForcedDisconnectException occurred then report it as actual
           // problem.
-          if (shutdownCause instanceof MemberDisconnectedException) {
+          if (shutdownCause instanceof ForcedDisconnectException) {
             problem = (Exception) shutdownCause;
           } else {
             Throwable ne = problem;
@@ -750,7 +741,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
         }
         final String channelClosed =
             "Channel closed";
-        throw new MembershipClosedException(channelClosed, problem);
+        throw new DistributedSystemDisconnectedException(channelClosed, problem);
       }
     } // useMcast
     else { // ! useMcast
@@ -782,14 +773,8 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       for (ID mbr : calculatedMembers) {
         short version = mbr.getVersionOrdinal();
         if (!messages.containsKey(version)) {
-          org.jgroups.Message jmsg;
-          try {
-            jmsg = createJGMessage(msg, local, mbr, version);
-            messages.put(version, jmsg);
-          } catch (IOException e) {
-            failedRecipients.add(mbr);
-            continue;
-          }
+          org.jgroups.Message jmsg = createJGMessage(msg, local, mbr, version);
+          messages.put(version, jmsg);
           if (firstMessage) {
             theStats.incSentBytes(jmsg.getLength());
             firstMessage = false;
@@ -803,9 +788,6 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
         JGAddress to = new JGAddress(mbr);
         short version = mbr.getVersionOrdinal();
         org.jgroups.Message jmsg = messages.get(version);
-        if (jmsg == null) {
-          continue; // failed for all recipients
-        }
         Exception problem = null;
         try {
           org.jgroups.Message tmp = (i < (calculatedLen - 1)) ? jmsg.copy(true) : jmsg;
@@ -824,7 +806,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
           if (cause != null) {
             // If ForcedDisconnectException occurred then report it as actual
             // problem.
-            if (cause instanceof MemberDisconnectedException) {
+            if (cause instanceof ForcedDisconnectException) {
               problem = (Exception) cause;
             } else {
               Throwable ne = problem;
@@ -836,7 +818,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
           }
           final String channelClosed =
               "Channel closed";
-          throw new MembershipClosedException(channelClosed, problem);
+          throw new DistributedSystemDisconnectedException(channelClosed, problem);
         }
       } // send individually
     } // !useMcast
@@ -844,19 +826,20 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
     // The contract is that every destination enumerated in the
     // message should have received the message. If one left
     // (i.e., left the view), we signal it here.
-    if (failedRecipients.isEmpty() && msg.forAll()) {
+    if (msg.forAll()) {
       return Collections.emptySet();
     }
+    Set<ID> result = new HashSet<>();
     GMSMembershipView<ID> newView = this.view;
     if (newView != null && newView != oldView) {
       for (ID d : destinations) {
         if (!newView.contains(d)) {
           logger.debug("messenger: member has left the view: {}  view is now {}", d, newView);
-          failedRecipients.add(d);
+          result.add(d);
         }
       }
     }
-    return failedRecipients;
+    return result;
   }
 
   /**
@@ -870,7 +853,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
    * @return the new message
    */
   org.jgroups.Message createJGMessage(Message<ID> gfmsg, JGAddress src, ID dst,
-      short version) throws IOException {
+      short version) {
     gfmsg.registerProcessor();
     org.jgroups.Message msg = new org.jgroups.Message();
     msg.setDest(null);
@@ -892,13 +875,19 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
 
       msg.setBuffer(out_stream.toByteArray());
       services.getStatistics().endMsgSerialization(start);
-    } catch (IOException ex) {
+    } catch (IOException | GemFireIOException ex) {
       logger.warn("Error serializing message", ex);
-      throw ex;
+      if (ex instanceof GemFireIOException) {
+        throw (GemFireIOException) ex;
+      } else {
+        GemFireIOException ioe = new GemFireIOException("Error serializing message");
+        ioe.initCause(ex);
+        throw ioe;
+      }
     } catch (Exception ex) {
       logger.warn("Error serializing message", ex);
-      IOException ioe =
-          new IOException("Error serializing message", ex.getCause());
+      GemFireIOException ioe = new GemFireIOException("Error serializing message");
+      ioe.initCause(ex.getCause());
       throw ioe;
     }
     return msg;
@@ -1038,7 +1027,7 @@ public class JGroupsMessenger<ID extends MemberIdentifier> implements Messenger<
       boolean isEncrypted = dis.readBoolean();
 
       if (isEncrypted && encrypt == null) {
-        throw new MembershipConfigurationException("Got remote message as encrypted");
+        throw new GemFireConfigException("Got remote message as encrypted");
       }
 
       if (isEncrypted) {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
index 1983d8e..bfb1b38 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
@@ -754,48 +754,44 @@ public class SocketCreator {
    */
   public ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog,
       boolean isBindAddress, boolean useNIO, int tcpBufferSize, int[] tcpPortRange,
-      boolean sslConnection) {
+      boolean sslConnection) throws IOException {
 
-    try {
-      // Get a random port from range.
-      int startingPort = tcpPortRange[0]
-          + ThreadLocalRandom.current().nextInt(tcpPortRange[1] - tcpPortRange[0] + 1);
-      int localPort = startingPort;
-      int portLimit = tcpPortRange[1];
-
-      while (true) {
-        if (localPort > portLimit) {
-          if (startingPort != 0) {
-            localPort = tcpPortRange[0];
-            portLimit = startingPort - 1;
-            startingPort = 0;
-          } else {
-            throw new SystemConnectException(
-                "Unable to find a free port in the membership-port-range");
-          }
+    // Get a random port from range.
+    int startingPort = tcpPortRange[0]
+        + ThreadLocalRandom.current().nextInt(tcpPortRange[1] - tcpPortRange[0] + 1);
+    int localPort = startingPort;
+    int portLimit = tcpPortRange[1];
+
+    while (true) {
+      if (localPort > portLimit) {
+        if (startingPort != 0) {
+          localPort = tcpPortRange[0];
+          portLimit = startingPort - 1;
+          startingPort = 0;
+        } else {
+          throw new SystemConnectException(
+              "Unable to find a free port in the membership-port-range");
         }
-        ServerSocket socket = null;
-        try {
-          if (useNIO) {
-            ServerSocketChannel channel = ServerSocketChannel.open();
-            socket = channel.socket();
+      }
+      ServerSocket socket = null;
+      try {
+        if (useNIO) {
+          ServerSocketChannel channel = ServerSocketChannel.open();
+          socket = channel.socket();
 
-            InetSocketAddress address = new InetSocketAddress(isBindAddress ? ba : null, localPort);
-            socket.bind(address, backlog);
-          } else {
-            socket = this.createServerSocket(localPort, backlog, isBindAddress ? ba : null,
-                tcpBufferSize, sslConnection);
-          }
-          return socket;
-        } catch (java.net.SocketException ex) {
-          if (socket != null && !socket.isClosed()) {
-            socket.close();
-          }
-          localPort++;
+          InetSocketAddress address = new InetSocketAddress(isBindAddress ? ba : null, localPort);
+          socket.bind(address, backlog);
+        } else {
+          socket = this.createServerSocket(localPort, backlog, isBindAddress ? ba : null,
+              tcpBufferSize, sslConnection);
+        }
+        return socket;
+      } catch (java.net.SocketException ex) {
+        if (socket != null && !socket.isClosed()) {
+          socket.close();
         }
+        localPort++;
       }
-    } catch (IOException e) {
-      throw new GemFireConfigException("unable to create a socket in the membership-port range", e);
     }
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
index 927e46a..2554723 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
@@ -72,7 +72,6 @@ import org.apache.geode.distributed.internal.ReplyProcessor21;
 import org.apache.geode.distributed.internal.ReplySender;
 import org.apache.geode.distributed.internal.direct.DirectChannel;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.internal.Assert;
 import org.apache.geode.internal.DSFIDFactory;
@@ -2655,6 +2654,8 @@ public class Connection implements Runnable {
       stats.incMessageChannelTime(msg.resetTimestamp());
       msg.process(dm, processor);
       // dispatchMessage(msg, len, false);
+    } catch (MemberShunnedException e) {
+      // do nothing
     } catch (SocketTimeoutException timeout) {
       throw timeout;
     } catch (IOException e) {
@@ -3170,8 +3171,7 @@ public class Connection implements Runnable {
     }
   }
 
-  private boolean dispatchMessage(DistributionMessage msg, int bytesRead, boolean directAck)
-      throws MemberShunnedException {
+  private boolean dispatchMessage(DistributionMessage msg, int bytesRead, boolean directAck) {
     try {
       msg.setDoDecMessagesBeingReceived(true);
       if (directAck) {
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberShunnedException.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/MemberShunnedException.java
similarity index 88%
rename from geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberShunnedException.java
rename to geode-core/src/main/java/org/apache/geode/internal/tcp/MemberShunnedException.java
index 9bd010d..6b4e9bd 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/api/MemberShunnedException.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/MemberShunnedException.java
@@ -13,14 +13,16 @@
  * the License.
  */
 
-package org.apache.geode.distributed.internal.membership.gms.api;
+package org.apache.geode.internal.tcp;
+
+import org.apache.geode.GemFireException;
 
 /**
  * MemberShunnedException may be thrown to prevent ack-ing a message received from a member that has
  * been removed from membership. It is currently only thrown by
  * JGroupMembershipManager.processMessage()
  */
-public class MemberShunnedException extends Exception {
+public class MemberShunnedException extends GemFireException {
   private static final long serialVersionUID = -8453126202477831557L;
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
index a5a53fd..e553c54 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
@@ -48,7 +48,6 @@ import org.apache.geode.distributed.internal.DistributionMessage;
 import org.apache.geode.distributed.internal.LonerDistributionManager;
 import org.apache.geode.distributed.internal.direct.DirectChannel;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.distributed.internal.membership.gms.api.MemberShunnedException;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.net.BufferPool;
@@ -656,8 +655,7 @@ public class TCPConduit implements Runnable {
    *
    * @param bytesRead number of bytes read off of network to get this message
    */
-  void messageReceived(Connection receiver, DistributionMessage message, int bytesRead)
-      throws MemberShunnedException {
+  void messageReceived(Connection receiver, DistributionMessage message, int bytesRead) {
     if (logger.isTraceEnabled()) {
       logger.trace("{} received {} from {}", id, message, receiver);
     }
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index 5fefafa..ca18ac8 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -259,11 +259,6 @@ org/apache/geode/distributed/internal/deadlock/MessageDependencyMonitor$MessageK
 org/apache/geode/distributed/internal/direct/ShunnedMemberException,true,-6455664684151074915
 org/apache/geode/distributed/internal/locks/DistributedMemberLock$LockReentryPolicy,false
 org/apache/geode/distributed/internal/locks/LockGrantorDestroyedException,true,-3540124531032570817
-org/apache/geode/distributed/internal/membership/gms/api/MemberDisconnectedException,true,-3649273301807236514
-org/apache/geode/distributed/internal/membership/gms/api/MemberShunnedException,true,-8453126202477831557
-org/apache/geode/distributed/internal/membership/gms/api/MemberStartupException,true,6610743861046044144
-org/apache/geode/distributed/internal/membership/gms/api/MembershipClosedException,true,6112938405434046127
-org/apache/geode/distributed/internal/membership/gms/api/MembershipConfigurationException,true,5633602142465129621
 org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave$ViewAbandonedException,false
 org/apache/geode/distributed/internal/membership/gms/messages/InstallViewMessage$messageType,false
 org/apache/geode/internal/ConfigSource,true,-4097017272431018553,description:java/lang/String,type:org/apache/geode/internal/ConfigSource$Type
@@ -416,6 +411,7 @@ org/apache/geode/internal/tcp/ByteBufferInputStream,false,buffer:org/apache/geod
 org/apache/geode/internal/tcp/ConnectExceptions,true,-4173688946448867706,causes:java/util/List,members:java/util/List
 org/apache/geode/internal/tcp/ConnectionException,true,-1977443644277412122
 org/apache/geode/internal/tcp/ImmutableByteBufferInputStream,false
+org/apache/geode/internal/tcp/MemberShunnedException,true,-8453126202477831557
 org/apache/geode/internal/tcp/ReenteredConnectException,true,2878977454669428469
 org/apache/geode/internal/util/Breadcrumbs$CrumbType,false
 org/apache/geode/internal/util/SunAPINotFoundException,true,75895915344106684
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionTest.java
index 73ce133..629f16a 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionTest.java
@@ -45,7 +45,6 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe
 import org.apache.geode.distributed.internal.membership.gms.GMSMemberData;
 import org.apache.geode.distributed.internal.membership.gms.GMSMembership;
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipClosedException;
 import org.apache.geode.internal.admin.remote.AlertListenerMessage;
 import org.apache.geode.internal.admin.remote.RemoteTransportConfig;
 import org.apache.geode.internal.tcp.ConnectExceptions;
@@ -139,7 +138,7 @@ public class DistributionTest {
         .directChannelSend(recipients, m);
     when(dc.send(any(), any(mockMembers.getClass()),
         any(DistributionMessage.class), anyInt(), anyInt())).thenReturn(0);
-    doThrow(MembershipClosedException.class).when(membership).checkCancelled();
+    doThrow(DistributedSystemDisconnectedException.class).when(membership).checkCancelled();
 
     try {
       distribution.directChannelSend(recipients, m);
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
index 4e09ad8..55217da 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
@@ -15,6 +15,7 @@
 package org.apache.geode.distributed.internal.membership;
 
 import static com.tngtech.archunit.base.DescribedPredicate.not;
+import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
 import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
 import static com.tngtech.archunit.core.domain.JavaClass.Predicates.type;
 import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
@@ -28,6 +29,9 @@ import com.tngtech.archunit.junit.CacheMode;
 import com.tngtech.archunit.lang.ArchRule;
 import org.junit.runner.RunWith;
 
+import org.apache.geode.CancelCriterion;
+import org.apache.geode.GemFireException;
+import org.apache.geode.InternalGemFireError;
 import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.LocatorStats;
@@ -106,9 +110,16 @@ public class MembershipDependenciesJUnitTest {
               // TODO: Create a new stats interface for membership
               .or(type(LocatorStats.class))
 
+              // TODO: Figure out what to do with exceptions
+              .or(assignableTo(GemFireException.class))
+              .or(type(InternalGemFireError.class))
+
               // TODO: Serialization needs to become its own module
               .or(type(InternalDataSerializer.class)) // still used by GMSLocator
 
+              // TODO
+              .or(assignableTo(CancelCriterion.class))
+
               // TODO:
               .or(type(SocketCreator.class))
               .or(type(SocketCreatorFactory.class))
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
index 6c6c3dd..bc04765 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
@@ -27,7 +27,7 @@ import junitparams.Parameters;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.apache.geode.distributed.internal.membership.gms.api.MembershipConfigurationException;
+import org.apache.geode.GemFireConfigException;
 import org.apache.geode.distributed.internal.membership.gms.membership.HostAddress;
 
 @RunWith(JUnitParamsRunner.class)
@@ -43,7 +43,7 @@ public class GMSUtilTest {
 
 
   @Test
-  public void resolveableLoopBackAddress() throws MembershipConfigurationException {
+  public void resolveableLoopBackAddress() {
     assertThat(
         parseLocators(RESOLVEABLE_LOOPBACK_HOST + "[" + PORT + "]",
             InetAddress.getLoopbackAddress()))
@@ -57,7 +57,7 @@ public class GMSUtilTest {
     assertThatThrownBy(
         () -> parseLocators(RESOLVEABLE_NON_LOOPBACK_HOST + "[" + PORT + "]",
             InetAddress.getLoopbackAddress()))
-                .isInstanceOf(MembershipConfigurationException.class)
+                .isInstanceOf(GemFireConfigException.class)
                 .hasMessageContaining("does not have a local address");
   }
 
@@ -66,13 +66,13 @@ public class GMSUtilTest {
     assertThatThrownBy(
         () -> parseLocators(UNRESOLVEABLE_HOST + "[" + PORT + "]",
             InetAddress.getLoopbackAddress()))
-                .isInstanceOf(MembershipConfigurationException.class)
+                .isInstanceOf(GemFireConfigException.class)
                 .hasMessageContaining("unknown address or FQDN: " + UNRESOLVEABLE_HOST);
   }
 
   @Test
   @Parameters({"1234", "0"})
-  public void validPortSpecified(final int validPort) throws MembershipConfigurationException {
+  public void validPortSpecified(final int validPort) {
     final String locatorsString = RESOLVEABLE_LOOPBACK_HOST + "[" + validPort + "]";
     assertThat(parseLocators(locatorsString, InetAddress.getLoopbackAddress()))
         .contains(
@@ -86,14 +86,13 @@ public class GMSUtilTest {
     final String locatorsString = RESOLVEABLE_LOOPBACK_HOST + portSpecification;
     assertThatThrownBy(
         () -> parseLocators(locatorsString, InetAddress.getLoopbackAddress()))
-            .isInstanceOf(MembershipConfigurationException.class)
+            .isInstanceOf(GemFireConfigException.class)
             .hasMessageContaining("malformed port specification: " + locatorsString);
   }
 
   @Test
   @Parameters({"host@127.0.0.1[1234]", "host:127.0.0.1[1234]"})
-  public void validHostSpecified(final String locatorsString)
-      throws MembershipConfigurationException {
+  public void validHostSpecified(final String locatorsString) {
     assertThat(parseLocators(locatorsString, (InetAddress) null))
         .contains(
             new HostAddress(new InetSocketAddress("127.0.0.1", 1234), "127.0.0.1"));
@@ -101,8 +100,7 @@ public class GMSUtilTest {
 
   @Test
   @Parameters({"server1@fdf0:76cf:a0ed:9449::5[12233]", "fdf0:76cf:a0ed:9449::5[12233]"})
-  public void validIPV6AddySpecified(final String locatorsString)
-      throws MembershipConfigurationException {
+  public void validIPV6AddySpecified(final String locatorsString) {
     assertThat(parseLocators(locatorsString, (InetAddress) null))
         .contains(
             new HostAddress(new InetSocketAddress("fdf0:76cf:a0ed:9449::5", 12233),
diff --git a/geode-dunit/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipManagerHelper.java b/geode-dunit/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipManagerHelper.java
index df306ca..f246530 100644
--- a/geode-dunit/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipManagerHelper.java
+++ b/geode-dunit/src/main/java/org/apache/geode/distributed/internal/membership/gms/MembershipManagerHelper.java
@@ -24,8 +24,8 @@ import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.Distribution;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.distributed.internal.MembershipTestHook;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.distributed.internal.membership.gms.api.MembershipTestHook;
 import org.apache.geode.test.awaitility.GeodeAwaitility;
 import org.apache.geode.test.dunit.WaitCriterion;
 
@@ -78,12 +78,12 @@ public class MembershipManagerHelper {
 
   /** register a test hook with the manager */
   public static void addTestHook(DistributedSystem sys, MembershipTestHook hook) {
-    ((InternalDistributedSystem) sys).getDistributionManager().registerTestHook(hook);
+    getDistribution(sys).registerTestHook(hook);
   }
 
   /** remove a registered test hook */
   public static void removeTestHook(DistributedSystem sys, MembershipTestHook hook) {
-    ((InternalDistributedSystem) sys).getDistributionManager().unregisterTestHook(hook);
+    getDistribution(sys).unregisterTestHook(hook);
   }
 
   /**