You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by va...@apache.org on 2025/04/22 09:18:49 UTC

(qpid-broker-j) branch main updated: QPID-8664: [Broker-J] Guava removal (5/10)

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

vavrtom pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git


The following commit(s) were added to refs/heads/main by this push:
     new d8778ef002 QPID-8664: [Broker-J] Guava removal (5/10)
d8778ef002 is described below

commit d8778ef00241e96fa814fe14c973f5b4310cc129
Author: dakirily <da...@gmail.com>
AuthorDate: Thu Mar 27 10:10:55 2025 +0100

    QPID-8664: [Broker-J] Guava removal (5/10)
    
    This commit replaces guava ListenableFuture with JDK CompletableFuture in ConfiguredObject descendants and in other remaining places
---
 .../store/berkeleydb/AbstractBDBMessageStore.java  |   1 -
 .../store/berkeleydb/CoalescingCommiter.java       |   3 -
 .../replication/ReplicatedEnvironmentFacade.java   |   2 -
 .../berkeleydb/BDBHARemoteReplicationNodeImpl.java |  13 +-
 .../berkeleydb/BDBHAVirtualHostNodeImpl.java       | 147 ++--
 .../berkeleydb/replication/GroupBrokerAdmin.java   |  23 +-
 .../model/ConfiguredObjectFactoryGenerator.java    |  18 +-
 .../org/apache/qpid/server/SystemLauncher.java     |   4 +-
 .../server/consumer/AbstractConsumerTarget.java    |   9 +-
 .../qpid/server/consumer/ConsumerTarget.java       |   4 +-
 .../qpid/server/exchange/AbstractExchange.java     |   9 +-
 .../server/model/AbstractConfiguredObject.java     | 790 +++++++--------------
 .../model/AbstractConfiguredObjectTypeFactory.java |  32 +-
 .../qpid/server/model/AbstractSystemConfig.java    |  80 +--
 .../org/apache/qpid/server/model/BrokerImpl.java   | 113 ++-
 .../apache/qpid/server/model/ConfiguredObject.java |  21 +-
 .../qpid/server/model/ConfiguredObjectFactory.java |   5 +-
 .../server/model/ConfiguredObjectFactoryImpl.java  |   9 +-
 .../server/model/ConfiguredObjectTypeRegistry.java |   6 +-
 .../java/org/apache/qpid/server/model/Port.java    |   5 +-
 .../org/apache/qpid/server/model/Producer.java     |   4 +-
 .../org/apache/qpid/server/model/ProducerImpl.java |  10 +-
 .../java/org/apache/qpid/server/model/Queue.java   |   5 +-
 .../model/adapter/FileBasedGroupProviderImpl.java  |  58 +-
 .../qpid/server/model/port/AbstractPort.java       |  11 +-
 .../qpid/server/model/port/AmqpPortImpl.java       |  15 +-
 .../apache/qpid/server/model/port/PortFactory.java |   9 +-
 .../server/plugin/ConfiguredObjectTypeFactory.java |   5 +-
 .../apache/qpid/server/queue/AbstractQueue.java    |  73 +-
 .../qpid/server/queue/QueueConsumerImpl.java       |  14 +-
 .../org/apache/qpid/server/queue/QueueFactory.java |   9 +-
 .../qpid/server/security/AbstractKeyStore.java     |   9 +-
 .../qpid/server/security/AbstractTrustStore.java   |   9 +-
 .../AllowAllAccessControlProviderImpl.java         |  12 +-
 .../AutoGeneratedSelfSignedKeyStoreImpl.java       |   7 +-
 .../qpid/server/security/FileKeyStoreImpl.java     |   8 +-
 .../qpid/server/security/FileTrustStoreImpl.java   |   8 +-
 .../ManagedPeerCertificateTrustStoreImpl.java      |   7 +-
 .../qpid/server/security/NonJavaKeyStoreImpl.java  |   8 +-
 .../server/security/NonJavaTrustStoreImpl.java     |   7 +-
 .../security/SiteSpecificTrustStoreImpl.java       |  54 +-
 .../access/AbstractAccessControlProvider.java      |   8 +-
 .../manager/AbstractAuthenticationManager.java     |  11 +-
 .../AbstractScramAuthenticationManager.java        |   5 +-
 ...odelPasswordManagingAuthenticationProvider.java |  18 +-
 .../server/security/auth/manager/ManagedUser.java  |   5 +-
 .../PrincipalDatabaseAuthenticationManager.java    |  46 +-
 .../qpid/server/security/group/GroupImpl.java      |   8 +-
 .../server/security/group/GroupMemberImpl.java     |   8 +-
 .../server/security/group/GroupProviderImpl.java   |  12 +-
 ...oundryDashboardManagementGroupProviderImpl.java |   8 +-
 .../apache/qpid/server/session/AMQPSession.java    |   4 +-
 .../qpid/server/session/AbstractAMQPSession.java   |  11 +-
 .../qpid/server/store/MemoryMessageStore.java      |   3 -
 .../qpid/server/transport/AMQPConnection.java      |   5 +-
 .../server/transport/AbstractAMQPConnection.java   |  50 +-
 .../qpid/server/transport/SelectorThread.java      |   6 +-
 .../AbstractNonConnectionAcceptingVirtualHost.java |   7 +-
 .../server/virtualhost/AbstractVirtualHost.java    | 272 ++++---
 .../AsynchronousMessageStoreRecoverer.java         |  19 +-
 .../server/virtualhost/MessageStoreRecoverer.java  |   4 +-
 .../virtualhost/QueueManagingVirtualHost.java      |   5 +-
 .../SynchronousMessageStoreRecoverer.java          |   7 +-
 .../AbstractStandardVirtualHostNode.java           |  63 +-
 .../virtualhostnode/AbstractVirtualHostNode.java   |  83 +--
 .../RedirectingVirtualHostNodeImpl.java            |  67 +-
 .../store/ManagementModeStoreHandlerTest.java      |  11 +-
 .../qpid/server/consumer/TestConsumerTarget.java   |   8 +-
 .../apache/qpid/server/model/VirtualHostTest.java  |   7 +-
 .../hierarchy/AbstractConfiguredObjectTest.java    |  46 +-
 .../hierarchy/TestAbstractEngineImpl.java          |  22 +-
 .../hierarchy/TestAbstractGaugeImpl.java           |   8 +-
 .../hierarchy/TestAbstractInstrumentPanelImpl.java |   8 +-
 .../hierarchy/TestAbstractSensorImpl.java          |   8 +-
 .../model/testmodels/hierarchy/TestEngine.java     |   6 +-
 .../lifecycle/AbstractConfiguredObjectTest.java    |   5 +-
 .../testmodels/lifecycle/TestConfiguredObject.java |  14 +-
 .../encryption/AESGCMKeyFileEncrypterTest.java     |   6 +-
 .../AsynchronousMessageStoreRecovererTest.java     |   8 +-
 .../AbstractStandardVirtualHostNodeTest.java       |   8 +-
 .../AbstractLegacyAccessControlProvider.java       |   7 +-
 .../plugins/AclFileAccessControlProviderImpl.java  |   7 +-
 .../server/protocol/v0_10/ServerSessionTest.java   |   5 +-
 .../protocol/v1_0/AMQPConnection_1_0Impl.java      |   8 +-
 .../apache/qpid/server/protocol/v1_0/LinkImpl.java |  67 +-
 .../apache/qpid/server/protocol/v1_0/Link_1_0.java |   4 +-
 .../qpid/server/protocol/v1_0/Session_1_0.java     | 125 ++--
 .../qpid/server/protocol/v1_0/LinkImplTest.java    |  10 +-
 .../qpid/server/protocol/v1_0/Session_1_0Test.java |   7 +-
 .../plugins/AbstractConnectionLimitProvider.java   |  15 +-
 .../logback/validator/TestConfiguredObject.java    |  46 +-
 .../validator/TestConfiguredObjectFactory.java     |  10 +-
 .../validator/TestConfiguredObjectTypeFactory.java |  10 +-
 .../logging/logback/jdbc/JDBCBrokerLoggerImpl.java |   6 +-
 .../store/jdbc/AbstractJDBCMessageStore.java       |   6 +-
 .../server/logging/logback/AbstractLogger.java     |   9 +-
 .../AbstractNameAndLevelLogInclusionRule.java      |   9 +-
 .../logback/AbstractPredicateLogInclusionRule.java |   9 +-
 .../logging/logback/BrokerFileLoggerImpl.java      |   9 +-
 .../server/management/amqp/ProxyMessageSource.java |   4 +-
 .../server/management/plugin/HttpManagement.java   |  33 +-
 .../servlet/rest/RestUserPreferenceHandler.java    |   1 -
 .../EndToEndConversionTestBase.java                |  14 +-
 .../SimpleConversionTest.java                      |  56 +-
 .../qpid/tests/protocol/v1_0/Interaction.java      |  10 +-
 .../protocol/v1_0/messaging/DeleteOnCloseTest.java |   4 +-
 .../tests/protocol/AbstractFrameTransport.java     |  36 +-
 .../qpid/tests/protocol/AbstractInteraction.java   |  31 +-
 .../qpid/systests/admin/SpawnBrokerAdmin.java      |   7 +-
 .../org/apache/qpid/tests/utils/BrokerAdmin.java   |   5 +-
 .../utils/EmbeddedBrokerPerClassAdminImpl.java     |   9 +-
 .../tests/utils/ExternalQpidBrokerAdminImpl.java   |   4 +-
 .../tests/utils/LoggingBrokerAdminDecorator.java   |   4 +-
 113 files changed, 1285 insertions(+), 1838 deletions(-)

diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
index e5de3e0fb8..b570e18880 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
@@ -34,7 +34,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import com.sleepycat.bind.tuple.LongBinding;
 import com.sleepycat.je.Cursor;
 import com.sleepycat.je.Database;
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
index 9ab0d3958f..e1009b9bfa 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CoalescingCommiter.java
@@ -26,13 +26,10 @@ import java.util.Queue;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.sleepycat.je.Transaction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
index e08b0d2d01..364c7f12f0 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
@@ -50,8 +50,6 @@ import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java b/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
index 16fda98fbc..776dd09241 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHARemoteReplicationNodeImpl.java
@@ -26,12 +26,11 @@ import static org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHost
 import java.util.Date;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -124,11 +123,11 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         if (!_nodeLeft)
         {
-            SettableFuture<Void> future = SettableFuture.create();
+            CompletableFuture<Void> future = new CompletableFuture<>();
 
             String nodeName = getName();
             try
@@ -136,13 +135,13 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
                 _replicatedEnvironmentFacade.removeNodeFromGroup(nodeName);
                 getEventLogger().message(_virtualHostNodeLogSubject,
                                          HighAvailabilityMessages.DELETE(getName(), String.valueOf(Outcome.SUCCESS)));
-                future.set(null);
+                future.complete(null);
             }
             catch (RuntimeException e)
             {
                 getEventLogger().message(_virtualHostNodeLogSubject,
                                          HighAvailabilityMessages.DELETE(getName(), String.valueOf(Outcome.FAILURE)));
-                future.setException(e);
+                future.completeExceptionally(e);
             }
             return future;
         }
@@ -267,7 +266,7 @@ public class BDBHARemoteReplicationNodeImpl extends AbstractConfiguredObject<BDB
     }
 
     @Override
-    protected ListenableFuture<Void> deleteNoChecks()
+    protected CompletableFuture<Void> deleteNoChecks()
     {
         return super.deleteNoChecks();
     }
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
index 114cc41bbb..79c32660dc 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
@@ -35,6 +35,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -43,10 +44,6 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import com.sleepycat.je.DatabaseException;
 import com.sleepycat.je.LogWriteException;
 import com.sleepycat.je.rep.NodeState;
@@ -323,7 +320,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
     }
 
     @Override
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         if (LOGGER.isDebugEnabled())
         {
@@ -374,47 +371,33 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
             environmentFacade.setPermittedNodes(_permittedNodes);
         }
 
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
     @StateTransition( currentState = { State.UNINITIALIZED, State.ACTIVE, State.ERRORED }, desiredState = State.STOPPED )
-    protected ListenableFuture<Void> doStop()
+    protected CompletableFuture<Void> doStop()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
+        final CompletableFuture<Void> returnVal = new CompletableFuture<>();
 
-        ListenableFuture<Void> superFuture = super.doStop();
-        addFutureCallback(superFuture, new FutureCallback<>()
+        CompletableFuture<Void> superFuture = super.doStop();
+        superFuture.whenCompleteAsync((result, error) ->
         {
-            @Override
-            public void onSuccess(final Void result)
+            try
             {
-                doFinally();
-            }
+                closeEnvironment();
 
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                doFinally();
+                // closing the environment does not cause a state change.  Adjust the role
+                // so that our observers will see DETACHED rather than our previous role in the group.
+                _lastRole.set(NodeRole.DETACHED);
+                attributeSet(ROLE, _role, NodeRole.DETACHED);
             }
-
-            private void doFinally()
+            finally
             {
-                try
-                {
-                    closeEnvironment();
-
-                    // closing the environment does not cause a state change.  Adjust the role
-                    // so that our observers will see DETACHED rather than our previous role in the group.
-                    _lastRole.set(NodeRole.DETACHED);
-                    attributeSet(ROLE, _role, NodeRole.DETACHED);
-                }
-                finally
-                {
-                    returnVal.set(null);
-                }
+                returnVal.complete(null);
             }
         }, getTaskExecutor());
+
         return returnVal;
     }
 
@@ -435,48 +418,47 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
     }
 
     @Override
-    protected ListenableFuture<Void> beforeDelete()
+    protected CompletableFuture<Void> beforeDelete()
     {
         _isClosedOrDeleted = true;
         return super.beforeDelete();
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         final Set<InetSocketAddress> helpers = getRemoteNodeAddresses();
 
-        return doAfterAlways(closeVirtualHostIfExists(),
-                             () -> {
-
-                                 closeEnvironment();
-
-                                 DurableConfigurationStore configurationStore = getConfigurationStore();
-                                 if (configurationStore != null)
-                                 {
-                                     configurationStore.closeConfigurationStore();
-                                     configurationStore.onDelete(BDBHAVirtualHostNodeImpl.this);
-                                     getEventLogger().message(getVirtualHostNodeLogSubject(),
-                                                              HighAvailabilityMessages.DELETE(getName(),
-                                                                                              String.valueOf(Outcome.SUCCESS)));
-                                 }
-
-                                 if (!helpers.isEmpty())
-                                 {
-                                     try
-                                     {
-                                         new ReplicationGroupAdmin(_groupName, helpers).removeMember(getName());
-                                     }
-                                     catch(DatabaseException e)
-                                     {
-                                         LOGGER.warn(String.format(
-                                                 "The deletion of node %s on remote nodes failed due to: %s. To finish deletion a "
-                                                 + "removal of the node from any of remote nodes (%s) is required.",
-                                                 this, e.getMessage(), helpers));
-                                     }
-                                 }
-                                 onCloseOrDelete();
-                             });
+        return closeVirtualHostIfExists().whenComplete((result, error) ->
+        {
+
+            closeEnvironment();
+
+            DurableConfigurationStore configurationStore = getConfigurationStore();
+            if (configurationStore != null)
+            {
+                configurationStore.closeConfigurationStore();
+                configurationStore.onDelete(BDBHAVirtualHostNodeImpl.this);
+                getEventLogger().message(getVirtualHostNodeLogSubject(),
+                                         HighAvailabilityMessages.DELETE(getName(), String.valueOf(Outcome.SUCCESS)));
+            }
+
+            if (!helpers.isEmpty())
+            {
+                try
+                {
+                    new ReplicationGroupAdmin(_groupName, helpers).removeMember(getName());
+                }
+                catch(DatabaseException e)
+                {
+                    LOGGER.warn(String.format(
+                            "The deletion of node %s on remote nodes failed due to: %s. To finish deletion a "
+                            + "removal of the node from any of remote nodes (%s) is required.",
+                            this, e.getMessage(), helpers));
+                }
+            }
+            onCloseOrDelete();
+        });
     }
 
     private Set<InetSocketAddress> getRemoteNodeAddresses()
@@ -494,9 +476,9 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
-        return doAfterAlways(super.onClose(), this::closeEnvironment);
+        return super.onClose().whenComplete((result, error) -> closeEnvironment());
     }
 
     @Override
@@ -724,7 +706,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
         createChild(VirtualHost.class, hostAttributes);
     }
 
-    protected ListenableFuture<Void> closeVirtualHostIfExist()
+    protected CompletableFuture<Void> closeVirtualHostIfExist()
     {
         final VirtualHost<?> virtualHost = getVirtualHost();
         if (virtualHost != null)
@@ -733,12 +715,12 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         _isClosedOrDeleted = true;
         return super.beforeClose();
@@ -1100,10 +1082,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
             if (remoteNode != null)
             {
                 remoteNode.setNodeLeft(true);
-                doAfter(remoteNode.deleteNoChecks(),
-                        () -> getEventLogger().message(getGroupLogSubject(),
-                                                 HighAvailabilityMessages.REMOVED(remoteNode.getName(),
-                                                                                  remoteNode.getAddress())));
+                remoteNode.deleteNoChecks().whenComplete((result, error) -> getEventLogger().message(getGroupLogSubject(),
+                        HighAvailabilityMessages.REMOVED(remoteNode.getName(), remoteNode.getAddress())));
             }
         }
 
@@ -1305,24 +1285,17 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
         final State initialState = getState();
 
 
-        ListenableFuture<Void> future = doAfterAlways(stopAndSetStateTo(State.ERRORED), () ->
+        CompletableFuture<Void> future = stopAndSetStateTo(State.ERRORED).whenCompleteAsync((result, error) ->
         {
             _lastRole.set(NodeRole.DETACHED);
             attributeSet(ROLE, _role, NodeRole.DETACHED);
             notifyStateChanged(initialState, State.ERRORED);
-        });
-
-        addFutureCallback(future, new FutureCallback<>()
+        }, getTaskExecutor())
+        .whenCompleteAsync((result, error) ->
         {
-            @Override
-            public void onSuccess(final Void result)
-            {
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
+            if (error != null)
             {
-                LOGGER.error("Failed to close children when handling intruder", t);
+                LOGGER.error("Failed to close children when handling intruder", error);
             }
         }, getTaskExecutor());
     }
diff --git a/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupBrokerAdmin.java b/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupBrokerAdmin.java
index e538f58a07..ae2f3ac7cd 100644
--- a/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupBrokerAdmin.java
+++ b/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupBrokerAdmin.java
@@ -31,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
@@ -41,8 +42,6 @@ import java.util.stream.Stream;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.sleepycat.je.rep.ReplicationConfig;
@@ -112,7 +111,7 @@ public class GroupBrokerAdmin
         GroupMember first = _members[0];
         first.getAdmin().beforeTestMethod(_members[0].getName(), NODE_TYPE, _members[0].getNodeAttributes());
         awaitNodeRoleReplicaOrMaster(first);
-        ListenableFuture<Void> f;
+        CompletableFuture<Void> f;
         if (_members.length > 2)
         {
             f = invokeParallel(Arrays.stream(_members).skip(1).map(m -> (Callable<Void>) () -> {
@@ -127,7 +126,7 @@ public class GroupBrokerAdmin
                 _members[i].getAdmin()
                            .beforeTestMethod(_members[i].getName(), NODE_TYPE, _members[i].getNodeAttributes());
             }
-            f = Futures.immediateFuture(null);
+            f = CompletableFuture.completedFuture(null);
         }
 
         awaitFuture(WAIT_LIMIT, f);
@@ -168,7 +167,7 @@ public class GroupBrokerAdmin
         }
     }
 
-    public ListenableFuture<Void> restart()
+    public CompletableFuture<Void> restart()
     {
         awaitFuture(WAIT_LIMIT, invokeParallel(Arrays.stream(_members).map(m -> (Callable<Void>) () -> {
             m.getAdmin().restart();
@@ -176,7 +175,7 @@ public class GroupBrokerAdmin
         }).collect(Collectors.toList())));
         awaitAllTransitionIntoReplicaOrMaster();
 
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     public void stop()
@@ -399,23 +398,23 @@ public class GroupBrokerAdmin
                              String.format("Could not find node by amqp port %d", amqpPort)));
     }
 
-    private <T> ListenableFuture<T> invokeParallel(Collection<Callable<T>> tasks)
+    private <T> CompletableFuture<T> invokeParallel(Collection<Callable<T>> tasks)
     {
         try
         {
             @SuppressWarnings("unchecked")
-            List<ListenableFuture<T>> futures = (List) _executorService.invokeAll(tasks);
-            ListenableFuture<List<T>> combinedFuture = Futures.allAsList(futures);
-            return Futures.transform(combinedFuture, input -> null, _executorService);
+            List<CompletableFuture<T>> futures = (List) _executorService.invokeAll(tasks);
+            CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
+            return combinedFuture.thenComposeAsync(input -> null, _executorService);
         }
         catch (InterruptedException e)
         {
             Thread.interrupted();
-            return Futures.immediateFailedFuture(e);
+            return CompletableFuture.failedFuture(e);
         }
     }
 
-    private <T> void awaitFuture(long waitLimit, ListenableFuture<T> future)
+    private <T> void awaitFuture(long waitLimit, CompletableFuture<T> future)
     {
         try
         {
diff --git a/broker-codegen/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryGenerator.java b/broker-codegen/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryGenerator.java
index 7d7db641a3..3a3600f142 100644
--- a/broker-codegen/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryGenerator.java
+++ b/broker-codegen/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryGenerator.java
@@ -133,11 +133,9 @@ public class ConfiguredObjectFactoryGenerator extends AbstractProcessor
             pw.println("import static org.apache.qpid.server.security.access.Operation.INVOKE_METHOD;");
             pw.println();
             pw.println("import java.util.Map;");
+            pw.println("import java.util.concurrent.CompletableFuture;");
             pw.println("import java.util.concurrent.ExecutionException;");
             pw.println();
-            pw.println("import com.google.common.util.concurrent.Futures;");
-            pw.println("import com.google.common.util.concurrent.ListenableFuture;");
-            pw.println();
             pw.println("import org.apache.qpid.server.configuration.updater.Task;");
             pw.println("import org.apache.qpid.server.util.FixedKeyMapCreator;");
             pw.println();
@@ -409,13 +407,13 @@ public class ConfiguredObjectFactoryGenerator extends AbstractProcessor
         StringWriter stringWriter = new StringWriter();
         PrintWriter pw = new PrintWriter(stringWriter);
         String boxedReturnTypeName = getBoxedReturnTypeAsString(methodElement);
-        pw.println("doSync(doOnConfigThread(new Task<ListenableFuture<"
+        pw.println("doSync(doOnConfigThread(new Task<CompletableFuture<"
                    + boxedReturnTypeName
                    + ">, RuntimeException>()");
         pw.println("            {");
         pw.println("                private String _args;");
         pw.println("                @Override");
-        pw.println("                public ListenableFuture<"
+        pw.println("                public CompletableFuture<"
                    + boxedReturnTypeName
                    + "> execute()");
         pw.println("                {");
@@ -427,9 +425,9 @@ public class ConfiguredObjectFactoryGenerator extends AbstractProcessor
         }
         if (methodElement.getReturnType().getKind() != TypeKind.VOID)
         {
-            pw.println("                    return Futures.<"
+            pw.println("                    return CompletableFuture.<"
                        + boxedReturnTypeName
-                       + ">immediateFuture("
+                       + ">completedFuture("
                        + className
                        + "."
                        + callToWrap
@@ -438,9 +436,9 @@ public class ConfiguredObjectFactoryGenerator extends AbstractProcessor
         else
         {
             pw.println("                    " + className + "." + callToWrap + ";");
-            pw.println("                    return Futures.<"
+            pw.println("                    return CompletableFuture.<"
                        + boxedReturnTypeName
-                       + ">immediateFuture(null);");
+                       + ">completedFuture(null);");
         }
         if (!thrownTypes.isEmpty())
         {
@@ -449,7 +447,7 @@ public class ConfiguredObjectFactoryGenerator extends AbstractProcessor
                                   .map(TypeMirror::toString)
                                   .collect(Collectors.joining(" | ", "                    catch (", " e)")));
             pw.println("                    {");
-            pw.println("                        return Futures.immediateFailedFuture(e);");
+            pw.println("                        return CompletableFuture.failedFuture(e);");
             pw.println("                    }");
         }
         pw.println("                }");
diff --git a/broker-core/src/main/java/org/apache/qpid/server/SystemLauncher.java b/broker-core/src/main/java/org/apache/qpid/server/SystemLauncher.java
index 8b3ebd43ff..d25892536c 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/SystemLauncher.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/SystemLauncher.java
@@ -35,13 +35,13 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -158,7 +158,7 @@ public class SystemLauncher
         {
             if(_systemConfig != null)
             {
-                ListenableFuture<Void> closeResult = _systemConfig.closeAsync();
+                CompletableFuture<Void> closeResult = _systemConfig.closeAsync();
                 closeResult.get(30000L, TimeUnit.MILLISECONDS);
             }
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/consumer/AbstractConsumerTarget.java b/broker-core/src/main/java/org/apache/qpid/server/consumer/AbstractConsumerTarget.java
index 33c6bbe395..bb86e1d4a6 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/consumer/AbstractConsumerTarget.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/consumer/AbstractConsumerTarget.java
@@ -23,13 +23,12 @@ package org.apache.qpid.server.consumer;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -160,7 +159,7 @@ public abstract class AbstractConsumerTarget<T extends AbstractConsumerTarget<T>
     }
 
     @Override
-    public ListenableFuture<Void> consumerRemoved(final MessageInstanceConsumer sub)
+    public CompletableFuture<Void> consumerRemoved(final MessageInstanceConsumer sub)
     {
         if(_consumers.contains(sub))
         {
@@ -169,11 +168,11 @@ public abstract class AbstractConsumerTarget<T extends AbstractConsumerTarget<T>
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
-    private ListenableFuture<Void> doOnIoThreadAsync(final Runnable task)
+    private CompletableFuture<Void> doOnIoThreadAsync(final Runnable task)
     {
         return getSession().getAMQPConnection().doOnIOThreadAsync(task);
     }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java b/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
index 0f5a111d92..a9665a0ad7 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/consumer/ConsumerTarget.java
@@ -20,7 +20,7 @@
  */
 package org.apache.qpid.server.consumer;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.message.MessageInstance;
 import org.apache.qpid.server.message.MessageInstanceConsumer;
@@ -53,7 +53,7 @@ public interface ConsumerTarget<T extends ConsumerTarget<T>>
 
     void consumerAdded(MessageInstanceConsumer<T> sub);
 
-    ListenableFuture<Void> consumerRemoved(MessageInstanceConsumer<T> sub);
+    CompletableFuture<Void> consumerRemoved(MessageInstanceConsumer<T> sub);
 
     long getUnacknowledgedBytes();
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 93ace0be8c..70eb54be44 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -40,8 +41,6 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -937,14 +936,14 @@ public abstract class AbstractExchange<T extends AbstractExchange<T>>
 
     @SuppressWarnings("unused")
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         if (getState() != State.UNINITIALIZED)
         {
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
index ef1f837224..cd97fb51b3 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
@@ -49,12 +49,13 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
@@ -66,12 +67,6 @@ import javax.security.auth.Subject;
 import javax.security.auth.SubjectDomainCombiner;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
 
 import org.apache.qpid.server.logging.CreateLogMessage;
 import org.apache.qpid.server.logging.DeleteLogMessage;
@@ -79,6 +74,7 @@ import org.apache.qpid.server.logging.LogMessage;
 import org.apache.qpid.server.logging.Outcome;
 import org.apache.qpid.server.logging.UpdateLogMessage;
 
+import com.google.common.util.concurrent.MoreExecutors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -126,9 +122,9 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     private static class DynamicStateWithFuture
     {
         private final DynamicState _dynamicState;
-        private final ListenableFuture<Void> _future;
+        private final CompletableFuture<Void> _future;
 
-        private DynamicStateWithFuture(final DynamicState dynamicState, final ListenableFuture<Void> future)
+        private DynamicStateWithFuture(final DynamicState dynamicState, final CompletableFuture<Void> future)
         {
             _dynamicState = dynamicState;
             _future = future;
@@ -139,7 +135,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             return _dynamicState;
         }
 
-        public ListenableFuture<Void> getFuture()
+        public CompletableFuture<Void> getFuture()
         {
             return _future;
         }
@@ -147,10 +143,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     private static final DynamicStateWithFuture UNINIT = new DynamicStateWithFuture(
             DynamicState.UNINIT,
-            Futures.immediateFuture(null));
+            CompletableFuture.completedFuture(null));
     private static final DynamicStateWithFuture OPENED = new DynamicStateWithFuture(
             DynamicState.OPENED,
-            Futures.immediateFuture(null));
+            CompletableFuture.completedFuture(null));
 
 
     private final AtomicReference<DynamicStateWithFuture> _dynamicState = new AtomicReference<>(UNINIT);
@@ -225,7 +221,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     private State _desiredState;
 
 
-    private volatile SettableFuture<ConfiguredObject<X>> _attainStateFuture = SettableFuture.create();
+    private volatile CompletableFuture<ConfiguredObject<X>> _attainStateFuture = new CompletableFuture<>();
     private boolean _openComplete;
     private boolean _openFailed;
     private volatile State _state = State.UNINITIALIZED;
@@ -433,7 +429,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
     }
 
-    private static final void findBestFitInterface(Class<? extends ConfiguredObject> clazz, Set<Class<? extends ConfiguredObject>> candidates)
+    private static void findBestFitInterface(Class<? extends ConfiguredObject> clazz, Set<Class<? extends ConfiguredObject>> candidates)
     {
         for(Class<?> interfaceClass : clazz.getInterfaces())
         {
@@ -561,12 +557,12 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
 
     @Override
-    public final ListenableFuture<Void> openAsync()
+    public final CompletableFuture<Void> openAsync()
     {
-        return doOnConfigThread(new Task<ListenableFuture<Void>, RuntimeException>()
+        return doOnConfigThread(new Task<CompletableFuture<Void>, RuntimeException>()
                                 {
                                     @Override
-                                    public ListenableFuture<Void> execute()
+                                    public CompletableFuture<Void> execute()
                                     {
                                         if (_dynamicState.compareAndSet(UNINIT, OPENED))
                                         {
@@ -583,12 +579,12 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                                             catch (RuntimeException e)
                                             {
                                                 exceptionHandler.handleException(e, AbstractConfiguredObject.this);
-                                                return Futures.immediateFuture(null);
+                                                return CompletableFuture.completedFuture(null);
                                             }
                                         }
                                         else
                                         {
-                                            return Futures.immediateFuture(null);
+                                            return CompletableFuture.completedFuture(null);
                                         }
                                     }
 
@@ -613,9 +609,9 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     }
 
-    protected final <T, E extends Exception> ListenableFuture<T> doOnConfigThread(final Task<ListenableFuture<T>, E> task)
+    protected final <T, E extends Exception> CompletableFuture<T> doOnConfigThread(final Task<CompletableFuture<T>, E> task)
     {
-        final SettableFuture<T> returnVal = SettableFuture.create();
+        final CompletableFuture<T> returnVal = new CompletableFuture<>();
 
         _taskExecutor.submit(new Task<Void, RuntimeException>()
         {
@@ -625,24 +621,21 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             {
                 try
                 {
-                    addFutureCallback(task.execute(), new FutureCallback<>()
+                    task.execute().whenCompleteAsync((result, throwable) ->
                     {
-                        @Override
-                        public void onSuccess(final T result)
+                        if (throwable != null)
                         {
-                            returnVal.set(result);
+                            returnVal.completeExceptionally(throwable);
                         }
-
-                        @Override
-                        public void onFailure(final Throwable t)
+                        else
                         {
-                            returnVal.setException(t);
+                            returnVal.complete(result);
                         }
                     }, getTaskExecutor());
                 }
                 catch(Throwable t)
                 {
-                    returnVal.setException(t);
+                    returnVal.completeExceptionally(t);
                 }
                 return null;
             }
@@ -669,8 +662,6 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         return returnVal;
     }
 
-
-
     public void registerWithParents()
     {
         if(_parent instanceof AbstractConfiguredObject<?>)
@@ -684,55 +675,47 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     }
 
-    protected final ListenableFuture<Void> closeChildren()
+    protected final CompletableFuture<Void> closeChildren()
     {
-        final List<ListenableFuture<Void>> childCloseFutures = new ArrayList<>();
+        final List<CompletableFuture<Void>> childCloseFutures = new ArrayList<>();
 
         applyToChildren(child ->
         {
-            ListenableFuture<Void> childCloseFuture = child.closeAsync();
-            addFutureCallback(childCloseFuture, new FutureCallback<>()
+            CompletableFuture<Void> childCloseFuture = child.closeAsync();
+            childCloseFuture.whenCompleteAsync((result, throwable) ->
             {
-                @Override
-                public void onSuccess(final Void result)
-                {
-                }
-
-                @Override
-                public void onFailure(final Throwable t)
+                if (throwable != null)
                 {
-                    LOGGER.error("Exception occurred while closing {} : {}",
-                                 child.getClass().getSimpleName(), child.getName(), t);
+                    LOGGER.error("Exception occurred while closing {} : {}", child.getClass().getSimpleName(), child.getName(), throwable);
                 }
             }, getTaskExecutor());
             childCloseFutures.add(childCloseFuture);
         });
-        ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(childCloseFutures);
-        return doAfter(combinedFuture, () ->
+        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(childCloseFutures.toArray(CompletableFuture[]::new));
+        return combinedFuture.thenRunAsync(() ->
         {
             // TODO consider removing each child from the parent as each child close completes, rather
             // than awaiting the completion of the combined future.  This would make it easy to give
             // clearer debug that would highlight the children that have failed to closed.
-            for(Collection<ConfiguredObject<?>> childList : _children.values())
+            for (Collection<ConfiguredObject<?>> childList : _children.values())
             {
                 childList.clear();
             }
 
-            for(Map<UUID,ConfiguredObject<?>> childIdMap : _childrenById.values())
+            for (Map<UUID,ConfiguredObject<?>> childIdMap : _childrenById.values())
             {
                 childIdMap.clear();
             }
 
-            for(Map<String,ConfiguredObject<?>> childNameMap : _childrenByName.values())
+            for (Map<String,ConfiguredObject<?>> childNameMap : _childrenByName.values())
             {
                 childNameMap.clear();
             }
 
             LOGGER.debug("All children closed {} : {}", AbstractConfiguredObject.this.getClass().getSimpleName(), getName());
-        });
+        }, getTaskExecutor());
     }
 
-
     @Override
     public void close()
     {
@@ -740,46 +723,42 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     }
 
     @Override
-    public final ListenableFuture<Void> closeAsync()
+    public final CompletableFuture<Void> closeAsync()
     {
-        return doOnConfigThread(new Task<ListenableFuture<Void>, RuntimeException>()
+        return doOnConfigThread(new Task<CompletableFuture<Void>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Void> execute()
+            public CompletableFuture<Void> execute()
             {
                 LOGGER.debug("Closing " + AbstractConfiguredObject.this.getClass().getSimpleName() + " : " + getName());
-                final SettableFuture<Void> returnFuture = SettableFuture.create();
+                final CompletableFuture<Void> returnFuture = new CompletableFuture<>();
                 DynamicStateWithFuture desiredStateWithFuture = new DynamicStateWithFuture(DynamicState.CLOSED, returnFuture);
                 DynamicStateWithFuture currentStateWithFuture;
                 while((currentStateWithFuture = _dynamicState.get()) == OPENED)
                 {
                     if(_dynamicState.compareAndSet(OPENED, desiredStateWithFuture))
                     {
-                        final ChainedListenableFuture<Void> future =
-                                doAfter(beforeClose(), () -> closeChildren()).then(() -> onClose())
-                                        .then(() ->
-                                        {
-                                            unregister(false);
-                                            LOGGER.debug("Closed "
-                                                    + AbstractConfiguredObject.this.getClass().getSimpleName()
-                                                    + " : "
-                                                    + getName());
-                                            return Futures.immediateFuture(null);
-                                        });
-                        addFutureCallback(future, new FutureCallback<>()
-                        {
-                            @Override
-                            public void onSuccess(final Void result)
-                            {
-                                returnFuture.set(null);
-                            }
-
-                            @Override
-                            public void onFailure(final Throwable t)
-                            {
-                                returnFuture.setException(t);
-                            }
-                        }, MoreExecutors.directExecutor());
+                        beforeClose()
+                                .thenComposeAsync(result -> closeChildren(), getTaskExecutor())
+                                .thenComposeAsync(result -> onClose(), getTaskExecutor())
+                                .thenComposeAsync(result ->
+                                {
+                                    unregister(false);
+                                    LOGGER.debug("Closed " + AbstractConfiguredObject.this.getClass().getSimpleName() +
+                                            " : " + getName());
+                                    return CompletableFuture.completedFuture(null);
+                                }, getTaskExecutor())
+                                .whenComplete((result, throwable) ->
+                                {
+                                    if (throwable != null)
+                                    {
+                                        returnFuture.completeExceptionally(throwable);
+                                    }
+                                    else
+                                    {
+                                        returnFuture.complete(null);
+                                    }
+                                });
 
                         return returnFuture;
                     }
@@ -810,14 +789,14 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     }
 
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     public final void create()
@@ -825,12 +804,12 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         doSync(createAsync());
     }
 
-    public final ListenableFuture<Void> createAsync()
+    public final CompletableFuture<Void> createAsync()
     {
-        return doOnConfigThread(new Task<ListenableFuture<Void>, RuntimeException>()
+        return doOnConfigThread(new Task<CompletableFuture<Void>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Void> execute()
+            public CompletableFuture<Void> execute()
             {
                 if (_dynamicState.compareAndSet(UNINIT, OPENED))
                 {
@@ -865,7 +844,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                         unregisteringExceptionHandler.handleException(e, AbstractConfiguredObject.this);
                     }
                 }
-                return Futures.immediateFuture(null);
+                return CompletableFuture.completedFuture(null);
 
             }
 
@@ -996,10 +975,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     {
     }
 
-    private ListenableFuture<Void> doAttainState(final AbstractConfiguredObjectExceptionHandler exceptionHandler,
-                                                 final Action<AbstractConfiguredObject<?>> postAction)
+    private CompletableFuture<Void> doAttainState(final AbstractConfiguredObjectExceptionHandler exceptionHandler,
+                                                  final Action<AbstractConfiguredObject<?>> postAction)
     {
-        final List<ListenableFuture<Void>> childStateFutures = new ArrayList<>();
+        final List<CompletableFuture<Void>> childStateFutures = new ArrayList<>();
 
         applyToChildren(child ->
         {
@@ -1020,75 +999,68 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             }
         });
 
-        ListenableFuture<List<Void>> combinedChildStateFuture = Futures.allAsList(childStateFutures);
+        CompletableFuture<Void> combinedChildStateFuture = CompletableFuture.allOf(childStateFutures.toArray(CompletableFuture[]::new));
 
-        final SettableFuture<Void> returnVal = SettableFuture.create();
-        addFutureCallback(combinedChildStateFuture, new FutureCallback<>()
+        final CompletableFuture<Void> returnVal = new CompletableFuture<>();
+
+        combinedChildStateFuture.whenCompleteAsync((result, error) ->
         {
-            @Override
-            public void onSuccess(final List<Void> result)
+            if (error != null)
+            {
+                // One or more children failed to attain state but the error could not be handled by the handler
+                returnVal.completeExceptionally(error);
+            }
+            else
             {
                 try
                 {
-                    addFutureCallback(attainState(),
-                                      new FutureCallback<>()
-                                      {
-                                          @Override
-                                          public void onSuccess(final Void result1)
-                                          {
-                                              postAction.performAction(AbstractConfiguredObject.this);
-                                              returnVal.set(null);
-                                          }
-
-                                          @Override
-                                          public void onFailure(final Throwable t)
-                                          {
-                                              try
-                                              {
-                                                  if (t instanceof RuntimeException)
-                                                  {
-                                                      try
-                                                      {
-                                                          exceptionHandler.handleException((RuntimeException) t,
-                                                                                           AbstractConfiguredObject.this);
-                                                          returnVal.set(null);
-                                                      }
-                                                      catch (RuntimeException r)
-                                                      {
-                                                          returnVal.setException(r);
-                                                      }
-                                                  }
-                                              }
-                                              finally
-                                              {
-                                                  if (!returnVal.isDone())
-                                                  {
-                                                      returnVal.setException(t);
-                                                  }
-                                              }
-                                          }
-                                      }, getTaskExecutor());
+                    attainState().whenCompleteAsync((result1, throwable) ->
+                    {
+                        if (throwable != null)
+                        {
+                            try
+                            {
+                                if (throwable instanceof RuntimeException)
+                                {
+                                    try
+                                    {
+                                        exceptionHandler.handleException((RuntimeException) throwable, AbstractConfiguredObject.this);
+                                        returnVal.complete(null);
+                                    }
+                                    catch (RuntimeException r)
+                                    {
+                                        returnVal.completeExceptionally(r);
+                                    }
+                                }
+                            }
+                            finally
+                            {
+                                if (!returnVal.isDone())
+                                {
+                                    returnVal.completeExceptionally(throwable);
+                                }
+                            }
+                        }
+                        else
+                        {
+                            postAction.performAction(AbstractConfiguredObject.this);
+                            returnVal.complete(null);
+                        }
+                    }, getTaskExecutor());
                 }
                 catch (RuntimeException e)
                 {
                     try
                     {
                         exceptionHandler.handleException(e, AbstractConfiguredObject.this);
-                        returnVal.set(null);
+                        returnVal.complete(null);
                     }
                     catch (Throwable t)
                     {
-                        returnVal.setException(t);
+                        returnVal.completeExceptionally(t);
                     }
                 }
             }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                // One or more children failed to attain state but the error could not be handled by the handler
-                returnVal.setException(t);
-            }
         }, getTaskExecutor());
 
         return returnVal;
@@ -1421,7 +1393,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
     }
 
-    private ListenableFuture<Void> attainStateIfOpenedOrReopenFailed()
+    private CompletableFuture<Void> attainStateIfOpenedOrReopenFailed()
     {
         if (_openComplete || getDesiredState() == State.DELETED)
         {
@@ -1431,7 +1403,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         {
             return openAsync();
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     protected void onOpen()
@@ -1439,34 +1411,40 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     }
 
-    protected ListenableFuture<Void> attainState()
+    protected CompletableFuture<Void> attainState()
     {
         return attainState(getDesiredState());
     }
 
-    private ListenableFuture<Void> attainState(State desiredState)
+    private CompletableFuture<Void> attainState(State desiredState)
     {
         final State currentState = getState();
-        ListenableFuture<Void> returnVal;
+        CompletableFuture<Void> returnVal;
 
         if (_attainStateFuture.isDone())
         {
-            _attainStateFuture = SettableFuture.create();
+            _attainStateFuture = new CompletableFuture<>();
         }
 
-        if(currentState != desiredState)
+        if (currentState != desiredState)
         {
             Method stateChangingMethod = getStateChangeMethod(currentState, desiredState);
             if(stateChangingMethod != null)
             {
                 try
                 {
-                    final SettableFuture<Void> stateTransitionResult = SettableFuture.create();
-                    ListenableFuture<Void> stateTransitionFuture = (ListenableFuture<Void>) stateChangingMethod.invoke(this);
-                    addFutureCallback(stateTransitionFuture, new FutureCallback<>()
+                    final CompletableFuture<Void> stateTransitionResult = new CompletableFuture<>();
+                    CompletableFuture<Void> stateTransitionFuture = (CompletableFuture<Void>) stateChangingMethod.invoke(this);
+                    stateTransitionFuture.whenCompleteAsync((result, throwable) ->
                     {
-                        @Override
-                        public void onSuccess(Void result)
+                        if (throwable != null)
+                        {
+                            // state transition failed to attain desired state
+                            // setting the _attainStateFuture, so, object relying on it could get the configured object
+                            _attainStateFuture.complete(AbstractConfiguredObject.this);
+                            stateTransitionResult.completeExceptionally(throwable);
+                        }
+                        else
                         {
                             try
                             {
@@ -1474,27 +1452,19 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                                 {
                                     notifyStateChanged(currentState, getState());
                                 }
-                                stateTransitionResult.set(null);
+                                stateTransitionResult.complete(null);
                             }
                             catch (Throwable e)
                             {
-                                stateTransitionResult.setException(e);
+                                stateTransitionResult.completeExceptionally(e);
                             }
                             finally
                             {
-                                _attainStateFuture.set(AbstractConfiguredObject.this);
+                                _attainStateFuture.complete(AbstractConfiguredObject.this);
                             }
                         }
-
-                        @Override
-                        public void onFailure(Throwable t)
-                        {
-                            // state transition failed to attain desired state
-                            // setting the _attainStateFuture, so, object relying on it could get the configured object
-                            _attainStateFuture.set(AbstractConfiguredObject.this);
-                            stateTransitionResult.setException(t);
-                        }
                     }, getTaskExecutor());
+
                     returnVal = stateTransitionResult;
                 }
                 catch (IllegalAccessException e)
@@ -1505,7 +1475,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                 {
                     // state transition failed to attain desired state
                     // setting the _attainStateFuture, so, object relying on it could get the configured object
-                    _attainStateFuture.set(this);
+                    _attainStateFuture.complete(this);
 
                     Throwable underlying = e.getTargetException();
                     if(underlying instanceof RuntimeException)
@@ -1521,14 +1491,14 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             }
             else
             {
-                returnVal = Futures.immediateFuture(null);
-                _attainStateFuture.set(this);
+                returnVal = CompletableFuture.completedFuture(null);
+                _attainStateFuture.complete(this);
             }
         }
         else
         {
-            returnVal = Futures.immediateFuture(null);
-            _attainStateFuture.set(this);
+            returnVal = CompletableFuture.completedFuture(null);
+            _attainStateFuture.complete(this);
         }
         return returnVal;
     }
@@ -1544,7 +1514,6 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         return method;
     }
 
-
     protected void onCreate()
     {
     }
@@ -1609,27 +1578,26 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         return _desiredState;
     }
 
-
-    private ListenableFuture<Void> setDesiredState(final State desiredState)
+    private CompletableFuture<Void> setDesiredState(final State desiredState)
             throws IllegalStateTransitionException, AccessControlException
     {
-        return doOnConfigThread(new Task<ListenableFuture<Void>, RuntimeException>()
+        return doOnConfigThread(new Task<CompletableFuture<Void>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Void> execute()
+            public CompletableFuture<Void> execute()
             {
                 final State state = getState();
                 final State currentDesiredState = getDesiredState();
-                if(desiredState == currentDesiredState && desiredState != state)
+                if (desiredState == currentDesiredState && desiredState != state)
                 {
-                    return doAfter(attainStateIfOpenedOrReopenFailed(), () ->
+                    return attainStateIfOpenedOrReopenFailed().whenCompleteAsync((result, error) ->
                     {
                         final State currentState = getState();
                         if (currentState != state)
                         {
                             notifyStateChanged(state, currentState);
                         }
-                    });
+                    }, getTaskExecutor());
                 }
                 else
                 {
@@ -1651,7 +1619,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                         }
                         else
                         {
-                            return Futures.immediateFuture(null);
+                            return CompletableFuture.completedFuture(null);
                         }
                     }
                 }
@@ -1693,7 +1661,6 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         _state = state;
     }
 
-
     protected void notifyStateChanged(final State currentState, final State desiredState)
     {
         List<ConfigurationChangeListener> copy;
@@ -1710,7 +1677,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     @Override
     public void addChangeListener(final ConfigurationChangeListener listener)
     {
-        if(listener == null)
+        if (listener == null)
         {
             throw new NullPointerException("Cannot add a null listener");
         }
@@ -1989,14 +1956,14 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     @SuppressWarnings("unchecked")
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> createChildAsync(final Class<C> childClass, final Map<String, Object> attributes)
+    public <C extends ConfiguredObject> CompletableFuture<C> createChildAsync(final Class<C> childClass, final Map<String, Object> attributes)
     {
-        return doOnConfigThread(new Task<ListenableFuture<C>, RuntimeException>()
+        return doOnConfigThread(new Task<CompletableFuture<C>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<C> execute()
+            public CompletableFuture<C> execute()
             {
-                ListenableFuture<C> result = null;
+                CompletableFuture<C> result = null;
                 try
                 {
                     result = create();
@@ -2011,16 +1978,16 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
                 return result;
             }
 
-            private ListenableFuture<C> create()
+            private CompletableFuture<C> create()
             {
                 authoriseCreateChild(childClass, attributes);
-                return doAfter(addChildAsync(childClass, attributes), child ->
+                return addChildAsync(childClass, attributes).thenApply(child ->
                 {
                     if (child != null)
                     {
                         childAdded(child);
                     }
-                    return Futures.immediateFuture(child);
+                    return child;
                 });
             }
 
@@ -2048,8 +2015,8 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         });
     }
 
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                             Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                              Map<String, Object> attributes)
     {
         return getObjectFactory().createAsync(childClass, attributes, this);
     }
@@ -2088,7 +2055,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         doSync(deleteAsync());
     }
 
-    protected final <R>  R doSync(ListenableFuture<R> async)
+    protected final <R> R doSync(CompletableFuture<R> async)
     {
         try
         {
@@ -2117,11 +2084,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             {
                 throw new ServerScopedRuntimeException(e);
             }
-
         }
     }
 
-    protected final <R>  R doSync(ListenableFuture<R> async, long timeout, TimeUnit units) throws TimeoutException
+    protected final <R> R doSync(CompletableFuture<R> async, long timeout, TimeUnit units) throws TimeoutException
     {
         try
         {
@@ -2155,32 +2121,31 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     }
 
     @Override
-    public final ListenableFuture<Void> deleteAsync()
+    public final CompletableFuture<Void> deleteAsync()
     {
         final State currentDesiredState = getDesiredState();
 
         if (currentDesiredState == State.DELETED)
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
-        ListenableFuture<Void> result = null;
+        CompletableFuture<Void> result = null;
         try
         {
             result = deleteWithChecks();
-            addFutureCallback(result, new FutureCallback<>()
+
+            result.whenComplete((result1, throwable) ->
             {
-                @Override
-                public void onSuccess(final Void result11)
+                if (throwable != null)
                 {
-                    logDeleted(Outcome.SUCCESS);
+                    logDeleted(Outcome.FAILURE);
                 }
-
-                @Override
-                public void onFailure(final Throwable t)
+                else
                 {
-                    logDeleted(Outcome.FAILURE);
+                    logDeleted(Outcome.SUCCESS);
                 }
-            }, MoreExecutors.directExecutor());
+            });
+
             return result;
         }
         finally
@@ -2192,7 +2157,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
     }
 
-    private ListenableFuture<Void> deleteWithChecks()
+    private CompletableFuture<Void> deleteWithChecks()
     {
         Map<String, Object> attributes = Collections.singletonMap(ConfiguredObject.DESIRED_STATE, State.DELETED);
         ConfiguredObject<?> proxyForValidation = createProxyForValidation(attributes);
@@ -2376,43 +2341,39 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         return false;
     }
 
-    protected ListenableFuture<Void> deleteNoChecks()
+    protected CompletableFuture<Void> deleteNoChecks()
     {
-        final String simpleClassName = AbstractConfiguredObject.this.getClass().getSimpleName();
-        final SettableFuture<Void> returnFuture = SettableFuture.create();
+        final CompletableFuture<Void> returnFuture = new CompletableFuture<>();
         final State currentDesiredState = getDesiredState();
 
-        final ChainedListenableFuture<Void> future =
-                doAfter(beforeDelete(), this::deleteChildren).then(this::onDelete)
-                                                             .then(() -> {
-                                                                 final State currentState = getState();
-                                                                 setState(State.DELETED);
-                                                                 notifyStateChanged(currentState, State.DELETED);
-                                                                 changeAttribute(ConfiguredObject.DESIRED_STATE, State.DELETED);
-                                                                 attributeSet(ConfiguredObject.DESIRED_STATE, currentDesiredState, State.DELETED);
-                                                                 unregister(true);
-
-                                                                 return Futures.immediateFuture(null);
-                                                                       });
-        addFutureCallback(future, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final Void result)
-            {
-                returnFuture.set(null);
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                returnFuture.setException(t);
-            }
-        }, MoreExecutors.directExecutor());
+        beforeDelete().thenComposeAsync(result -> deleteChildren(), getTaskExecutor())
+                .thenComposeAsync(result -> onDelete(), getTaskExecutor())
+                .thenComposeAsync(result ->
+                {
+                    final State currentState = getState();
+                    setState(State.DELETED);
+                    notifyStateChanged(currentState, State.DELETED);
+                    changeAttribute(ConfiguredObject.DESIRED_STATE, State.DELETED);
+                    attributeSet(ConfiguredObject.DESIRED_STATE, currentDesiredState, State.DELETED);
+                    unregister(true);
+                    return CompletableFuture.completedFuture(null);
+                }, getTaskExecutor())
+                .whenComplete((result, throwable) ->
+                {
+                    if (throwable != null)
+                    {
+                        returnFuture.completeExceptionally(throwable);
+                    }
+                    else
+                    {
+                        returnFuture.complete(null);
+                    }
+                });
 
         return returnFuture;
     }
 
-    protected final ListenableFuture<Void> deleteChildren()
+    protected final CompletableFuture<Void> deleteChildren()
     {
         // If this object manages its own child-storage then don't propagate the delete.  The rationale
         // is that deleting the object will delete the storage that contains the children.  Telling each
@@ -2420,14 +2381,14 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         // child-storage (which also might fail).
         if (managesChildStorage())
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
 
-        final List<ListenableFuture<Void>> childDeleteFutures = new ArrayList<>();
+        final List<CompletableFuture<Void>> childDeleteFutures = new ArrayList<>();
 
         applyToChildren(child -> {
 
-            final ListenableFuture<Void> childDeleteFuture;
+            final CompletableFuture<Void> childDeleteFuture;
             if (child instanceof AbstractConfiguredObject<?>)
             {
                  childDeleteFuture = ((AbstractConfiguredObject<?>) child).deleteNoChecks();
@@ -2438,48 +2399,45 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
             }
             else
             {
-                childDeleteFuture = Futures.immediateFuture(null);
+                childDeleteFuture = CompletableFuture.completedFuture(null);
             }
 
-            addFutureCallback(childDeleteFuture, new FutureCallback<>()
+            childDeleteFuture.whenCompleteAsync((result, throwable) ->
             {
-                @Override
-                public void onSuccess(final Void result)
+                if (throwable != null)
                 {
+                    LOGGER.error("Exception occurred while deleting {} : {}", child.getClass().getSimpleName(), child.getName(), throwable);
+
                     if (child instanceof AbstractConfiguredObject<?>)
                     {
-                        ((AbstractConfiguredObject) child).logDeleted(Outcome.SUCCESS);
+                        ((AbstractConfiguredObject) child).logDeleted(Outcome.FAILURE);
                     }
                 }
-
-                @Override
-                public void onFailure(final Throwable t)
+                else
                 {
-                    LOGGER.error("Exception occurred while deleting {} : {}",
-                                 child.getClass().getSimpleName(), child.getName(), t);
-
                     if (child instanceof AbstractConfiguredObject<?>)
                     {
-                        ((AbstractConfiguredObject) child).logDeleted(Outcome.FAILURE);
+                        ((AbstractConfiguredObject) child).logDeleted(Outcome.SUCCESS);
                     }
                 }
             }, getTaskExecutor());
+
             childDeleteFutures.add(childDeleteFuture);
         });
 
-        ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(childDeleteFutures);
+        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(childDeleteFutures.toArray(CompletableFuture[]::new));
 
-        return Futures.transform(combinedFuture, input -> null, getTaskExecutor());
+        return combinedFuture.thenApplyAsync(result -> null, getTaskExecutor());
     }
 
-    protected ListenableFuture<Void> beforeDelete()
+    protected CompletableFuture<Void> beforeDelete()
     {
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     public final void start()
@@ -2487,7 +2445,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         doSync(startAsync());
     }
 
-    public ListenableFuture<Void> startAsync()
+    public CompletableFuture<Void> startAsync()
     {
         return setDesiredState(State.ACTIVE);
     }
@@ -2499,28 +2457,26 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     private void unregister(boolean removed)
     {
-            if (_parent instanceof AbstractConfiguredObject<?>)
+        if (_parent instanceof AbstractConfiguredObject<?>)
+        {
+            AbstractConfiguredObject<?> parentObj = (AbstractConfiguredObject<?>) _parent;
+            parentObj.unregisterChild(this);
+            if (removed)
             {
-                AbstractConfiguredObject<?> parentObj = (AbstractConfiguredObject<?>) _parent;
-                parentObj.unregisterChild(this);
-                if(removed)
-                {
-                    parentObj.childRemoved(this);
-                }
+                parentObj.childRemoved(this);
             }
-            else if (_parent instanceof AbstractConfiguredObjectProxy)
+        }
+        else if (_parent instanceof AbstractConfiguredObjectProxy)
+        {
+            AbstractConfiguredObjectProxy parentObj = (AbstractConfiguredObjectProxy) _parent;
+            parentObj.unregisterChild(this);
+            if (removed)
             {
-                AbstractConfiguredObjectProxy parentObj = (AbstractConfiguredObjectProxy) _parent;
-                parentObj.unregisterChild(this);
-                if(removed)
-                {
-                    parentObj.childRemoved(this);
-                }
+                parentObj.childRemoved(this);
             }
-
+        }
     }
 
-
     private <C extends ConfiguredObject> void unregisterChild(final C child)
     {
         Class categoryClass = child.getCategoryClass();
@@ -2557,7 +2513,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     }
 
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildByName(final Class<C> childClass,
+    public <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildByName(final Class<C> childClass,
                                                                                    final String name)
     {
         C child = getChildByName(childClass, name);
@@ -2571,12 +2527,12 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
         else
         {
-            return Futures.immediateFuture(child);
+            return CompletableFuture.completedFuture(child);
         }
     }
 
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildById(final Class<C> childClass,
+    public <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildById(final Class<C> childClass,
                                                                                    final UUID id)
     {
         C child = getChildById(childClass, id);
@@ -2590,13 +2546,13 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
         else
         {
-            return Futures.immediateFuture(child);
+            return CompletableFuture.completedFuture(child);
         }
     }
 
-    private <C extends ConfiguredObject> ListenableFuture<C> getAttainStateFuture()
+    private <C extends ConfiguredObject> CompletableFuture<C> getAttainStateFuture()
     {
-        return (ListenableFuture<C>) _attainStateFuture;
+        return (CompletableFuture<C>) _attainStateFuture;
     }
 
     @Override
@@ -2626,262 +2582,8 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
     {
     }
 
-    protected final ChainedListenableFuture<Void> doAfter(ListenableFuture<?> first, final Runnable second)
-    {
-        return doAfter(getTaskExecutor(), first, second);
-    }
-
-    protected static <V> ChainedListenableFuture<Void>  doAfter(Executor executor, ListenableFuture<V> first, final Runnable second)
-    {
-        final ChainedSettableFuture<Void> returnVal = new ChainedSettableFuture<>(executor);
-        addFutureCallback(first, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final V result)
-            {
-                try
-                {
-                    second.run();
-                    returnVal.set(null);
-                }
-                catch (Throwable e)
-                {
-                    returnVal.setException(e);
-                }
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                returnVal.setException(t);
-            }
-        }, executor);
-
-        return returnVal;
-    }
-
-    public interface CallableWithArgument<V,A>
-    {
-        V call(A argument) throws Exception;
-    }
-
-    public static interface ChainedListenableFuture<V> extends ListenableFuture<V>
-    {
-        ChainedListenableFuture<Void> then(Runnable r);
-        ChainedListenableFuture<V> then(Callable<ListenableFuture<V>> r);
-        <A> ChainedListenableFuture<A> then(CallableWithArgument<ListenableFuture<A>,V> r);
-    }
-
-    public static class ChainedSettableFuture<V> extends AbstractFuture<V> implements ChainedListenableFuture<V>
-    {
-        private final Executor _exector;
-
-        public ChainedSettableFuture(final Executor executor)
-        {
-            _exector = executor;
-        }
-
-        @Override
-        public boolean set(V value)
-        {
-            return super.set(value);
-        }
-
-        @Override
-        public boolean setException(Throwable throwable)
-        {
-            return super.setException(throwable);
-        }
-
-        @Override
-        public ChainedListenableFuture<Void> then(final Runnable r)
-        {
-            return doAfter(_exector, this, r);
-        }
-
-        @Override
-        public ChainedListenableFuture<V> then(final Callable<ListenableFuture<V>> r)
-        {
-            return doAfter(_exector, this,r);
-        }
-
-        @Override
-        public <A> ChainedListenableFuture<A> then(final CallableWithArgument<ListenableFuture<A>,V> r)
-        {
-            return doAfter(_exector, this, r);
-        }
-    }
-
-    protected final <V> ChainedListenableFuture<V> doAfter(ListenableFuture<V> first, final Callable<ListenableFuture<V>> second)
-    {
-        return doAfter(getTaskExecutor(), first, second);
-    }
-
-    protected final <V,A> ChainedListenableFuture<V> doAfter(ListenableFuture<A> first, final CallableWithArgument<ListenableFuture<V>,A> second)
-    {
-        return doAfter(getTaskExecutor(), first, second);
-    }
-
-
-    protected static <V> ChainedListenableFuture<V> doAfter(final Executor executor, ListenableFuture<V> first, final Callable<ListenableFuture<V>> second)
-    {
-        final ChainedSettableFuture<V> returnVal = new ChainedSettableFuture<>(executor);
-        addFutureCallback(first, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final V result)
-            {
-                try
-                {
-                    final ListenableFuture<V> future = second.call();
-                    addFutureCallback(future, new FutureCallback<>()
-                    {
-                        @Override
-                        public void onSuccess(final V result)
-                        {
-                            returnVal.set(result);
-                        }
-
-                        @Override
-                        public void onFailure(final Throwable t)
-                        {
-                            returnVal.setException(t);
-                        }
-                    }, executor);
-                }
-                catch (Throwable e)
-                {
-                    returnVal.setException(e);
-                }
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                returnVal.setException(t);
-            }
-        }, executor);
-
-        return returnVal;
-    }
-
-
-    protected static <V,A> ChainedListenableFuture<V> doAfter(final Executor executor, ListenableFuture<A> first, final CallableWithArgument<ListenableFuture<V>,A> second)
-    {
-        final ChainedSettableFuture<V> returnVal = new ChainedSettableFuture<>(executor);
-        addFutureCallback(first, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final A result)
-            {
-                try
-                {
-                    final ListenableFuture<V> future = second.call(result);
-                    addFutureCallback(future, new FutureCallback<>()
-                    {
-                        @Override
-                        public void onSuccess(final V result)
-                        {
-                            returnVal.set(result);
-                        }
-
-                        @Override
-                        public void onFailure(final Throwable t)
-                        {
-                            returnVal.setException(t);
-                        }
-                    }, executor);
-                }
-                catch (Throwable e)
-                {
-                    returnVal.setException(e);
-                }
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                returnVal.setException(t);
-            }
-        }, executor);
-
-        return returnVal;
-    }
-    protected <V> ChainedListenableFuture<Void> doAfterAlways(ListenableFuture<V> future,
-                                                              Runnable after)
-    {
-        return doAfterAlways(getTaskExecutor(), future, after);
-    }
-
-    protected static <V> ChainedListenableFuture<Void> doAfterAlways(Executor executor,
-                                                                     ListenableFuture<V> future,
-                                                                     final Runnable after)
-    {
-        final ChainedSettableFuture<Void> returnVal = new ChainedSettableFuture<>(executor);
-        addFutureCallback(future, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final V result)
-            {
-                try
-                {
-                    after.run();
-                    returnVal.set(null);
-                }
-                catch (Throwable e)
-                {
-                    returnVal.setException(e);
-                }
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                try
-                {
-                    after.run();
-                }
-                finally
-                {
-                    returnVal.setException(t);
-                }
-            }
-        }, executor);
-
-        return returnVal;
-    }
-
-    public static <V> void addFutureCallback(ListenableFuture<V> future, final FutureCallback<V> callback,
-                                             Executor taskExecutor)
-    {
-        final Subject subject = Subject.getSubject(AccessController.getContext());
-
-        Futures.addCallback(future, new FutureCallback<>()
-        {
-            @Override
-            public void onSuccess(final V result)
-            {
-                Subject.doAs(subject, (PrivilegedAction<Void>) () ->
-                {
-                    callback.onSuccess(result);
-                    return null;
-                });
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                Subject.doAs(subject, (PrivilegedAction<Void>) () ->
-                {
-                    callback.onFailure(t);
-                    return null;
-                });
-            }
-        }, taskExecutor);
-    }
-
     @Override
-    public ListenableFuture<Void> setAttributesAsync(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException
+    public CompletableFuture<Void> setAttributesAsync(final Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException
     {
         final Map<String,Object> updateAttributes = new HashMap<>(attributes);
         Object desiredState = updateAttributes.remove(ConfiguredObject.DESIRED_STATE);
@@ -2951,7 +2653,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
@@ -3320,7 +3022,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     protected final <C extends ConfiguredObject> C awaitChildClassToAttainState(final Class<C> childClass, final String name)
     {
-        ListenableFuture<C> attainedChildByName = getAttainedChildByName(childClass, name);
+        CompletableFuture<C> attainedChildByName = getAttainedChildByName(childClass, name);
         try
         {
             return (C) doSync(attainedChildByName, getAwaitAttainmentTimeout(), TimeUnit.MILLISECONDS);
@@ -3334,7 +3036,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
     protected final <C extends ConfiguredObject> C awaitChildClassToAttainState(final Class<C> childClass, final UUID id)
     {
-        ListenableFuture<C> attainedChildByName = getAttainedChildById(childClass, id);
+        CompletableFuture<C> attainedChildByName = getAttainedChildById(childClass, id);
         try
         {
             return (C) doSync(attainedChildByName, getAwaitAttainmentTimeout(), TimeUnit.MILLISECONDS);
@@ -4062,7 +3764,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
         DynamicState getDynamicState();
 
-        ListenableFuture<Void> doAttainState(AbstractConfiguredObjectExceptionHandler exceptionHandler);
+        CompletableFuture<Void> doAttainState(AbstractConfiguredObjectExceptionHandler exceptionHandler);
 
         void doOpening(boolean skipCheck, AbstractConfiguredObjectExceptionHandler exceptionHandler);
 
@@ -4082,10 +3784,10 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
 
         void childRemoved(ConfiguredObject child);
 
-        ListenableFuture getAttainStateFuture();
+        CompletableFuture getAttainStateFuture();
 
         void forceUpdateAllSecureAttributes();
 
-        ListenableFuture<Void> deleteNoChecks();
+        CompletableFuture<Void> deleteNoChecks();
     }
 }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java
index 8e28029b95..d912cc4f4b 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java
@@ -22,11 +22,7 @@ package org.apache.qpid.server.model;
 
 import java.util.HashMap;
 import java.util.Map;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
 import org.apache.qpid.server.store.ConfiguredObjectDependency;
@@ -66,28 +62,24 @@ abstract public class AbstractConfiguredObjectTypeFactory<X extends AbstractConf
 
 
     @Override
-    public ListenableFuture<X> createAsync(final ConfiguredObjectFactory factory,
-                    final Map<String, Object> attributes,
-                    final ConfiguredObject<?> parent)
+    public CompletableFuture<X> createAsync(final ConfiguredObjectFactory factory,
+                                            final Map<String, Object> attributes,
+                                            final ConfiguredObject<?> parent)
     {
-        final SettableFuture<X> returnVal = SettableFuture.create();
+        final CompletableFuture<X> returnVal = new CompletableFuture<>();
         final X instance = createInstance(attributes, parent);
-        final ListenableFuture<Void> createFuture = instance.createAsync();
-        AbstractConfiguredObject.addFutureCallback(createFuture, new FutureCallback<>()
+        final CompletableFuture<Void> createFuture = instance.createAsync();
+        createFuture.whenComplete((result, throwable) ->
         {
-            @Override
-            public void onSuccess(final Void result)
+            if (throwable != null)
             {
-                returnVal.set(instance);
+                returnVal.completeExceptionally(throwable);
             }
-
-            @Override
-            public void onFailure(final Throwable t)
+            else
             {
-                returnVal.setException(t);
+                returnVal.complete(instance);
             }
-        }, MoreExecutors.directExecutor());
-
+        });
         return returnVal;
     }
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
index 7e4f37c4cf..a326ea731a 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
@@ -33,11 +33,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
@@ -137,7 +133,7 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         final TaskExecutor taskExecutor = getTaskExecutor();
         try
@@ -161,7 +157,7 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
                 taskExecutor.stopImmediately();
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -223,25 +219,29 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
 
 
     @StateTransition(currentState = State.ACTIVE, desiredState = State.STOPPED)
-    protected ListenableFuture<Void> doStop()
+    protected CompletableFuture<Void> doStop()
     {
-        return doAfter(getContainer().closeAsync(), () ->
+        final Container<?> container = getContainer();
+        if (container == null)
+        {
+            return CompletableFuture.completedFuture(null);
+        }
+        return container.closeAsync().thenRunAsync(() ->
         {
             _configurationStore.closeConfigurationStore();
             AbstractSystemConfig.super.setState(State.STOPPED);
-        });
-
+        }, getTaskExecutor());
     }
 
 
     @StateTransition(currentState = { State.UNINITIALIZED, State.STOPPED }, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
-        return doAfter(makeActive(), () -> AbstractSystemConfig.super.setState(State.ACTIVE));
+        return makeActive().thenRunAsync(() -> AbstractSystemConfig.super.setState(State.ACTIVE), getTaskExecutor());
     }
 
 
-    protected ListenableFuture<Void> makeActive()
+    protected CompletableFuture<Void> makeActive()
     {
 
         final EventLogger eventLogger = _eventLogger;
@@ -253,32 +253,28 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
             final Container<?> container = initiateStoreAndRecovery();
 
             container.setEventLogger(startupLogger);
-            final SettableFuture<Void> returnVal = SettableFuture.create();
-            addFutureCallback(container.openAsync(), new FutureCallback()
-                                {
-                                    @Override
-                                    public void onSuccess(final Object result)
-                                    {
-                                        State state = container.getState();
-                                        if (state == State.ACTIVE)
-                                        {
-                                            startupLogger.message(BrokerMessages.READY());
-                                            container.setEventLogger(eventLogger);
-                                            returnVal.set(null);
-                                        }
-                                        else
-                                        {
-                                            returnVal.setException(new ServerScopedRuntimeException("Broker failed reach ACTIVE state (state is " + state + ")"));
-                                        }
-                                    }
-
-                                    @Override
-                                    public void onFailure(final Throwable t)
-                                    {
-                                        returnVal.setException(t);
-                                    }
-                                }, getTaskExecutor()
-                               );
+            final CompletableFuture<Void> returnVal = new CompletableFuture<>();
+            container.openAsync().whenCompleteAsync((result, error) ->
+            {
+                if (error != null)
+                {
+                    returnVal.completeExceptionally(error);
+                }
+                else
+                {
+                    State state = container.getState();
+                    if (state == State.ACTIVE)
+                    {
+                        startupLogger.message(BrokerMessages.READY());
+                        container.setEventLogger(eventLogger);
+                        returnVal.complete(null);
+                    }
+                    else
+                    {
+                        returnVal.completeExceptionally(new ServerScopedRuntimeException("Broker failed reach ACTIVE state (state is " + state + ")"));
+                    }
+                }
+            }, getTaskExecutor());
 
             return returnVal;
         }
@@ -333,7 +329,7 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
 
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
-    protected ListenableFuture<Void> startQuiesced()
+    protected CompletableFuture<Void> startQuiesced()
     {
         final EventLogger startupLogger = initiateStartupLogging();
 
@@ -342,7 +338,7 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
             final Container<?> container = initiateStoreAndRecovery();
 
             container.setEventLogger(startupLogger);
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
         catch (IOException e)
         {
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/BrokerImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/BrokerImpl.java
index 234ccc9d63..0a0b6c0505 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/BrokerImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/BrokerImpl.java
@@ -35,6 +35,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
@@ -49,11 +50,6 @@ import java.util.regex.Pattern;
 import javax.security.auth.Subject;
 import javax.security.auth.login.AccountNotFoundException;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -319,26 +315,26 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
     }
 
     @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         if(_parent.isManagementMode())
         {
-            return doAfter(_managementModeAuthenticationProvider.openAsync(), this::performActivation);
+            return _managementModeAuthenticationProvider.openAsync().thenRunAsync(this::performActivation, getTaskExecutor());
         }
         else
         {
             performActivation();
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @SuppressWarnings("unused")
     @StateTransition( currentState = {State.ACTIVE, State.ERRORED}, desiredState = State.STOPPED )
-    private ListenableFuture<Void> doStop()
+    private CompletableFuture<Void> doStop()
     {
         stopPreferenceTaskExecutor();
         closePreferenceStore();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     private void closePreferenceStore()
@@ -461,21 +457,8 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
 
             _lastDisposalCounter = QpidByteBuffer.getPooledBufferDisposalCounter();
 
-            ListenableFuture<Void> result = compactMemoryInternal();
-            addFutureCallback(result, new FutureCallback<>()
-            {
-                @Override
-                public void onSuccess(final Void result)
-                {
-                    scheduleDirectMemoryCheck();
-                }
-
-                @Override
-                public void onFailure(final Throwable t)
-                {
-                    scheduleDirectMemoryCheck();
-                }
-            }, MoreExecutors.directExecutor());
+            CompletableFuture<Void> result = compactMemoryInternal()
+                    .whenComplete((result1, error) -> scheduleDirectMemoryCheck());
         }
         else
         {
@@ -656,36 +639,31 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
         return children;
     }
 
-    private ListenableFuture<VirtualHostNode> createVirtualHostNodeAsync(Map<String, Object> attributes)
+    private CompletableFuture<VirtualHostNode> createVirtualHostNodeAsync(Map<String, Object> attributes)
             throws AccessControlException, IllegalArgumentException
     {
 
-        return doAfter(getObjectFactory().createAsync(VirtualHostNode.class, attributes, this),
-                       new CallableWithArgument<ListenableFuture<VirtualHostNode>, VirtualHostNode>()
-                       {
-                           @Override
-                           public ListenableFuture<VirtualHostNode> call(final VirtualHostNode virtualHostNode)
-                           {
-                               // permission has already been granted to create the virtual host
-                               // disable further access check on other operations, e.g. create exchange
-                               Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<Object>) () ->
-                               {
-                                   virtualHostNode.start();
-                                   return null;
-                               });
-                               return Futures.immediateFuture(virtualHostNode);
-                           }
-                       });
+        return getObjectFactory().createAsync(VirtualHostNode.class, attributes, this).thenApplyAsync((virtualHostNode) ->
+        {
+            // permission has already been granted to create the virtual host
+            // disable further access check on other operations, e.g. create exchange
+            Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<Object>) () ->
+            {
+                ((VirtualHostNode) virtualHostNode).start();
+                return null;
+            });
+            return virtualHostNode;
+        }, getTaskExecutor());
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(final Class<C> childClass,
                                                                           final Map<String, Object> attributes)
     {
         if (childClass == VirtualHostNode.class)
         {
-            return (ListenableFuture<C>) createVirtualHostNodeAsync(attributes);
+            return (CompletableFuture<C>) createVirtualHostNodeAsync(attributes);
         }
         else
         {
@@ -694,7 +672,7 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         try
         {
@@ -710,7 +688,7 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         if (_assignTargetSizeSchedulingFuture != null)
         {
@@ -739,7 +717,7 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
                 task.run();
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
 
     }
 
@@ -998,8 +976,8 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
         {
             final SystemConfig<?> systemConfig = (SystemConfig) getParent();
             // This is deliberately asynchronous as the HTTP thread will be interrupted by restarting
-            doAfter(systemConfig.setAttributesAsync(Map.of(ConfiguredObject.DESIRED_STATE, State.STOPPED)), () ->
-                    systemConfig.setAttributesAsync(Map.of(ConfiguredObject.DESIRED_STATE, State.ACTIVE)));
+            systemConfig.setAttributesAsync(Map.of(ConfiguredObject.DESIRED_STATE, State.STOPPED))
+                    .thenRunAsync(() -> systemConfig.setAttributesAsync(Map.of(ConfiguredObject.DESIRED_STATE, State.ACTIVE)), getTaskExecutor());
             return null;
         });
 
@@ -1141,45 +1119,42 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
         compactMemoryInternal();
     }
 
-    private ListenableFuture<Void> compactMemoryInternal()
+    private CompletableFuture<Void> compactMemoryInternal()
     {
         LOGGER.debug("Compacting direct memory buffers: numberOfActivePooledBuffers: {}",
                      QpidByteBuffer.getNumberOfBuffersInUse());
 
         final Collection<VirtualHostNode<?>> vhns = getVirtualHostNodes();
-        List<ListenableFuture<Void>> futures = new ArrayList<>(vhns.size());
+        List<CompletableFuture<Void>> futures = new ArrayList<>(vhns.size());
         for (VirtualHostNode<?> vhn : vhns)
         {
             VirtualHost<?> vh = vhn.getVirtualHost();
             if (vh instanceof QueueManagingVirtualHost)
             {
-                ListenableFuture<Void> future = ((QueueManagingVirtualHost) vh).reallocateMessages();
+                CompletableFuture<Void> future = ((QueueManagingVirtualHost) vh).reallocateMessages();
                 futures.add(future);
             }
         }
 
-        SettableFuture<Void> resultFuture = SettableFuture.create();
-        final ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(futures);
-        addFutureCallback(combinedFuture, new FutureCallback<>()
+        CompletableFuture<Void> resultFuture = new CompletableFuture<>();
+        final CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
+        combinedFuture.whenCompleteAsync((result, error) ->
         {
-            @Override
-            public void onSuccess(final List<Void> result)
+            if (error != null)
+            {
+                LOGGER.warn("Unexpected error during direct memory compaction.", error);
+                resultFuture.completeExceptionally(error);
+            }
+            else
             {
                 if (LOGGER.isDebugEnabled())
                 {
-                    LOGGER.debug("After compact direct memory buffers: numberOfActivePooledBuffers: {}",
-                                 QpidByteBuffer.getNumberOfBuffersInUse());
+                    LOGGER.debug("After compact direct memory buffers: numberOfActivePooledBuffers: {}", QpidByteBuffer.getNumberOfBuffersInUse());
                 }
-                resultFuture.set(null);
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
-            {
-                LOGGER.warn("Unexpected error during direct memory compaction.", t);
-                resultFuture.setException(t);
+                resultFuture.complete(null);
             }
         }, _houseKeepingTaskExecutor);
+
         return resultFuture;
     }
 
@@ -1290,7 +1265,7 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
 
         private void waitForBrokerShutdown()
         {
-            final ListenableFuture<Void> closeResult = _parent.closeAsync();
+            final CompletableFuture<Void> closeResult = _parent.closeAsync();
             try
             {
                 if (_shutdownTimeout < 1)
@@ -1309,7 +1284,7 @@ public class BrokerImpl extends AbstractContainer<BrokerImpl> implements Broker<
         }
     }
 
-    private final SocketConnectionMetaData getConnectionMetaDataInternal()
+    private SocketConnectionMetaData getConnectionMetaDataInternal()
     {
         final Subject subject = Subject.getSubject(AccessController.getContext());
         final SocketConnectionPrincipal principal;
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
index 6f70709ffc..7c59375a65 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
@@ -26,11 +26,10 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.preferences.UserPreferences;
 import org.apache.qpid.server.security.SecurityToken;
@@ -246,16 +245,16 @@ public interface ConfiguredObject<X extends ConfiguredObject<X>> extends Context
     <C extends ConfiguredObject> C createChild(Class<C> childClass,
                                                Map<String, Object> attributes);
 
-    <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildById(Class<C> childClass,
-                                                                          UUID id);
+    <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildById(Class<C> childClass,
+                                                                           UUID id);
 
-    <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildByName(Class<C> childClass, String name);
+    <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildByName(Class<C> childClass, String name);
 
-    <C extends ConfiguredObject> ListenableFuture<C> createChildAsync(Class<C> childClass,
-                                                                      Map<String, Object> attributes);
+    <C extends ConfiguredObject> CompletableFuture<C> createChildAsync(Class<C> childClass,
+                                                                       Map<String, Object> attributes);
 
     void setAttributes(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException;
-    ListenableFuture<Void> setAttributesAsync(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException;
+    CompletableFuture<Void> setAttributesAsync(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException;
 
 
     @Override
@@ -270,12 +269,12 @@ public interface ConfiguredObject<X extends ConfiguredObject<X>> extends Context
     ConfiguredObjectRecord asObjectRecord();
 
     void open();
-    ListenableFuture<Void> openAsync();
+    CompletableFuture<Void> openAsync();
 
     void close();
-    ListenableFuture<Void> closeAsync();
+    CompletableFuture<Void> closeAsync();
 
-    ListenableFuture<Void> deleteAsync();
+    CompletableFuture<Void> deleteAsync();
 
     TaskExecutor getChildExecutor();
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactory.java b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactory.java
index 7ca3266762..31e8508141 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactory.java
@@ -22,8 +22,7 @@ package org.apache.qpid.server.model;
 
 import java.util.Collection;
 import java.util.Map;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
 import org.apache.qpid.server.store.ConfiguredObjectRecord;
@@ -36,7 +35,7 @@ public interface ConfiguredObjectFactory
 
     <X extends ConfiguredObject<X>> X create(Class<X> clazz, Map<String, Object> attributes, ConfiguredObject<?> parent);
 
-    <X extends ConfiguredObject<X>> ListenableFuture<X> createAsync(Class<X> clazz, Map<String, Object> attributes, ConfiguredObject<?> parent);
+    <X extends ConfiguredObject<X>> CompletableFuture<X> createAsync(Class<X> clazz, Map<String, Object> attributes, ConfiguredObject<?> parent);
 
     <X extends ConfiguredObject<X>> ConfiguredObjectTypeFactory<X> getConfiguredObjectTypeFactory(String category,
                                                                                                   String type);
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
index 2a876de789..764eb1ce57 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFactoryImpl.java
@@ -25,8 +25,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
 import org.apache.qpid.server.plugin.QpidServiceLoader;
@@ -135,9 +134,9 @@ public class ConfiguredObjectFactoryImpl implements ConfiguredObjectFactory
 
 
     @Override
-    public <X extends ConfiguredObject<X>> ListenableFuture<X> createAsync(Class<X> clazz,
-                                                    final Map<String, Object> attributes,
-                                                    final ConfiguredObject<?> parent)
+    public <X extends ConfiguredObject<X>> CompletableFuture<X> createAsync(Class<X> clazz,
+                                                                            final Map<String, Object> attributes,
+                                                                            final ConfiguredObject<?> parent)
     {
         ConfiguredObjectTypeFactory<X> factory = getConfiguredObjectTypeFactory(clazz, attributes, parent);
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
index c62a506b85..f317a22da1 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
@@ -43,12 +43,12 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Predicate;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -1084,7 +1084,7 @@ public class ConfiguredObjectTypeRegistry
         {
             if (m.isAnnotationPresent(StateTransition.class))
             {
-                if (ListenableFuture.class.isAssignableFrom(m.getReturnType()))
+                if (CompletableFuture.class.isAssignableFrom(m.getReturnType()))
                 {
                     if (m.getParameterTypes().length == 0)
                     {
@@ -1110,7 +1110,7 @@ public class ConfiguredObjectTypeRegistry
                 else
                 {
                     throw new ServerScopedRuntimeException(
-                            "A state transition method must return a ListenableFuture. Method "
+                            "A state transition method must return a CompletableFuture. Method "
                             + m.getName()
                             + " on "
                             + clazz.getName()
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Port.java b/broker-core/src/main/java/org/apache/qpid/server/model/Port.java
index dc0060fc46..e0f959aaaa 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/Port.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/Port.java
@@ -23,11 +23,10 @@ package org.apache.qpid.server.model;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import javax.net.ssl.SSLContext;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.CommonProperties;
 import org.apache.qpid.server.security.SubjectCreator;
 
@@ -131,7 +130,7 @@ public interface Port<X extends Port<X>> extends ConfiguredObject<X>
 
     void start();
 
-    ListenableFuture<Void> startAsync();
+    CompletableFuture<Void> startAsync();
 
     NamedAddressSpace getAddressSpace(String name);
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java b/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java
index a40e47cc58..f0ca3e0c36 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java
@@ -21,8 +21,8 @@
 package org.apache.qpid.server.model;
 
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.apache.qpid.server.message.MessageDestination;
 
 @ManagedObject(creatable = false, amqpName = "org.apache.qpid.Producer")
@@ -96,5 +96,5 @@ public interface Producer<X extends Producer<X>> extends ConfiguredObject<X>
     @ManagedOperation(description = "Resets producer statistics", changesConfiguredObjectState = true)
     void resetStatistics();
 
-    ListenableFuture<Void> deleteNoChecks();
+    CompletableFuture<Void> deleteNoChecks();
 }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java
index 2333eddb93..f715dc7b80 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java
@@ -23,12 +23,10 @@ package org.apache.qpid.server.model;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.message.MessageDestination;
 import org.apache.qpid.server.session.AbstractAMQPSession;
 
@@ -96,14 +94,14 @@ public class ProducerImpl<X extends Producer<X>>
 
     @SuppressWarnings("unused")
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    public ListenableFuture<Void> deleteNoChecks()
+    public CompletableFuture<Void> deleteNoChecks()
     {
         return super.deleteNoChecks();
     }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java b/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
index e40763d883..9ed950da35 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
@@ -24,8 +24,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.exchange.DestinationReferrer;
 import org.apache.qpid.server.logging.LogSubject;
@@ -380,7 +379,7 @@ public interface Queue<X extends Queue<X>> extends ConfiguredObject<X>,
 
     void visit(QueueEntryVisitor visitor);
 
-    ListenableFuture<Integer> deleteAndReturnCountAsync();
+    CompletableFuture<Integer> deleteAndReturnCountAsync();
 
     int deleteAndReturnCount();
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
index 4f04f98c68..b86f5c5cf8 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
@@ -30,9 +30,8 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -195,8 +194,8 @@ public class FileBasedGroupProviderImpl
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                          Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                              Map<String, Object> attributes)
     {
         if (childClass == Group.class)
         {
@@ -216,7 +215,7 @@ public class FileBasedGroupProviderImpl
             attrMap.put(ConfiguredObject.NAME, groupName);
             GroupAdapter groupAdapter = new GroupAdapter(attrMap);
             groupAdapter.create();
-            return Futures.immediateFuture((C) groupAdapter);
+            return CompletableFuture.completedFuture((C) groupAdapter);
         }
         else
         {
@@ -244,7 +243,7 @@ public class FileBasedGroupProviderImpl
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         if (_groupDatabase != null)
         {
@@ -261,33 +260,28 @@ public class FileBasedGroupProviderImpl
                 throw new IllegalConfigurationException(String.format("Cannot load groups from '%s'", getPath()));
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         // We manage the storage children so we close (so they may free any resources) them rather than deleting them
-        return doAfterAlways(closeChildren(),
-                             () -> {
-                                 File file = new File(getPath());
-                                 if (file.exists())
-                                 {
-                                     if (!file.delete())
-                                     {
-                                         throw new IllegalConfigurationException(String.format(
-                                                 "Cannot delete group file '%s'",
-                                                 file));
-                                     }
-                                 }
-                             });
+        return closeChildren().whenCompleteAsync((result, throwable) ->
+        {
+            final File file = new File(getPath());
+            if (file.exists() && !file.delete())
+            {
+                throw new IllegalConfigurationException(String.format("Cannot delete group file '%s'", file));
+            }
+        }, getTaskExecutor());
     }
 
     @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
-    private ListenableFuture<Void> startQuiesced()
+    private CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -327,10 +321,10 @@ public class FileBasedGroupProviderImpl
         }
 
         @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.ACTIVE )
-        private ListenableFuture<Void> activate()
+        private CompletableFuture<Void> activate()
         {
             setState(State.ACTIVE);
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
 
         @Override
@@ -354,8 +348,8 @@ public class FileBasedGroupProviderImpl
         }
 
         @Override
-        protected  <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                              Map<String, Object> attributes)
+        protected  <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                                   Map<String, Object> attributes)
         {
             if (childClass == GroupMember.class)
             {
@@ -367,7 +361,7 @@ public class FileBasedGroupProviderImpl
                 attrMap.put(GroupMember.NAME, memberName);
                 GroupMemberAdapter groupMemberAdapter = new GroupMemberAdapter(attrMap);
                 groupMemberAdapter.create();
-                return Futures.immediateFuture((C) groupMemberAdapter);
+                return CompletableFuture.completedFuture((C) groupMemberAdapter);
             }
             else
             {
@@ -376,7 +370,7 @@ public class FileBasedGroupProviderImpl
         }
 
         @Override
-        protected ListenableFuture<Void> onDelete()
+        protected CompletableFuture<Void> onDelete()
         {
             _groupDatabase.removeGroup(getName());
             return super.onDelete();
@@ -410,14 +404,14 @@ public class FileBasedGroupProviderImpl
             }
 
             @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
-            private ListenableFuture<Void> activate()
+            private CompletableFuture<Void> activate()
             {
                 setState(State.ACTIVE);
-                return Futures.immediateFuture(null);
+                return CompletableFuture.completedFuture(null);
             }
 
             @Override
-            protected ListenableFuture<Void> onDelete()
+            protected CompletableFuture<Void> onDelete()
             {
                 _groupDatabase.removeUserFromGroup(getName(), GroupAdapter.this.getName());
                 return super.onDelete();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java b/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
index 2e1ec3f3b2..008021c154 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
@@ -27,9 +27,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -374,7 +373,7 @@ public abstract class AbstractPort<X extends AbstractPort<X>> extends AbstractCo
     }
 
     @StateTransition( currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE )
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         try
         {
@@ -385,14 +384,14 @@ public abstract class AbstractPort<X extends AbstractPort<X>> extends AbstractCo
             setState(State.ERRORED);
             throw new IllegalConfigurationException("Unable to active port '" + getName() + "'of type " + getType() + " on " + getPort(), e);
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
-    private ListenableFuture<Void> startQuiesced()
+    private CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
index c7f41510c2..20942c5ae8 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
@@ -31,6 +31,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -39,8 +40,6 @@ import javax.net.ssl.SSLSessionContext;
 import javax.security.auth.Subject;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -291,28 +290,28 @@ public class AmqpPortImpl extends AbstractPort<AmqpPortImpl> implements AmqpPort
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         _closingOrDeleting.set(true);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         closeTransport();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> beforeDelete()
+    protected CompletableFuture<Void> beforeDelete()
     {
         _closingOrDeleting.set(true);
         return super.beforeDelete();
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         closeTransport();
         return super.onDelete();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java b/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
index 402343ba53..2d50735943 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/port/PortFactory.java
@@ -22,8 +22,7 @@ package org.apache.qpid.server.model.port;
 
 import java.util.Map;
 import java.util.Set;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
@@ -112,9 +111,9 @@ public class PortFactory<X extends Port<X>> implements ConfiguredObjectTypeFacto
     }
 
     @Override
-    public ListenableFuture<X> createAsync(final ConfiguredObjectFactory factory,
-                                           final Map<String, Object> attributes,
-                                           final ConfiguredObject<?> parent)
+    public CompletableFuture<X> createAsync(final ConfiguredObjectFactory factory,
+                                            final Map<String, Object> attributes,
+                                            final ConfiguredObject<?> parent)
     {
         return getPortFactory(factory, attributes, (Broker<?>) parent).createAsync(factory, attributes, parent);
     }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfiguredObjectTypeFactory.java b/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfiguredObjectTypeFactory.java
index d923ff91b6..b5ff58ffe7 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfiguredObjectTypeFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/plugin/ConfiguredObjectTypeFactory.java
@@ -21,8 +21,7 @@
 package org.apache.qpid.server.plugin;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFactory;
@@ -35,7 +34,7 @@ public interface ConfiguredObjectTypeFactory<X extends ConfiguredObject<X>> exte
 
     X create(final ConfiguredObjectFactory factory, Map<String, Object> attributes, ConfiguredObject<?> parent);
 
-    ListenableFuture<X> createAsync(final ConfiguredObjectFactory factory, Map<String, Object> attributes, ConfiguredObject<?> parent);
+    CompletableFuture<X> createAsync(final ConfiguredObjectFactory factory, Map<String, Object> attributes, ConfiguredObject<?> parent);
 
     UnresolvedConfiguredObject<X> recover(final ConfiguredObjectFactory factory,
                                           ConfiguredObjectRecord record,
diff --git a/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java b/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
index 709a3c65f1..6637d7b617 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
@@ -43,6 +43,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentMap;
@@ -60,11 +61,7 @@ import javax.security.auth.Subject;
 
 import com.google.common.collect.Lists;
 import com.google.common.io.ByteStreams;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -190,7 +187,7 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
     private final AtomicBoolean _stopped = new AtomicBoolean(false);
 
     private final AtomicBoolean _deleted = new AtomicBoolean(false);
-    private final SettableFuture<Integer> _deleteQueueDepthFuture = SettableFuture.create();
+    private final CompletableFuture<Integer> _deleteQueueDepthFuture = new CompletableFuture<>();
 
     private final List<Action<? super X>> _deleteTaskList = new CopyOnWriteArrayList<>();
 
@@ -1060,7 +1057,7 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         _closing = true;
         return super.beforeClose();
@@ -1975,19 +1972,19 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
     }
 
     @Override
-    public ListenableFuture<Integer> deleteAndReturnCountAsync()
+    public CompletableFuture<Integer> deleteAndReturnCountAsync()
     {
-        return Futures.transformAsync(deleteAsync(), v -> _deleteQueueDepthFuture, getTaskExecutor());
+        return deleteAsync().thenApplyAsync(v -> _deleteQueueDepthFuture.join(), getTaskExecutor());
     }
 
-    private ListenableFuture<Integer> performDelete()
+    private CompletableFuture<Integer> performDelete()
     {
         if (_deleted.compareAndSet(false, true))
         {
             if (getState() == State.UNINITIALIZED)
             {
                 preSetAlternateBinding();
-                _deleteQueueDepthFuture.set(0);
+                _deleteQueueDepthFuture.complete(0);
             }
             else
             {
@@ -2039,28 +2036,28 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
 
             performQueueDeleteTasks();
 
-            _deleteQueueDepthFuture.set(queueDepthMessages);
+            _deleteQueueDepthFuture.complete(queueDepthMessages);
 
             _transactions.clear();
         }
         catch(Throwable e)
         {
-            _deleteQueueDepthFuture.setException(e);
+            _deleteQueueDepthFuture.completeExceptionally(e);
         }
     }
 
     private void deleteAfterCompletionOfDischargingTransactions()
     {
-        final List<SettableFuture<Void>> dischargingTxs =
+        final List<CompletableFuture<Void>> dischargingTxs =
                 _transactions.stream()
                              .filter(t -> !t.isDischarged() && !t.isRollbackOnly() && !t.setRollbackOnly())
                              .map(t -> {
-                                 final SettableFuture<Void> future = SettableFuture.create();
-                                 LocalTransaction.LocalTransactionListener listener = tx -> future.set(null);
+                                 final CompletableFuture<Void> future = new CompletableFuture<>();
+                                 LocalTransaction.LocalTransactionListener listener = tx -> future.complete(null);
                                  t.addTransactionListener(listener);
                                  if (t.isRollbackOnly() || t.isDischarged())
                                  {
-                                     future.set(null);
+                                     future.complete(null);
                                      t.removeTransactionListener(listener);
                                  }
                                  return future;
@@ -2073,24 +2070,18 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
         }
         else
         {
-            ListenableFuture<Void> dischargingFuture = Futures.transform(Futures.allAsList(dischargingTxs),
-                                                                         input -> null,
-                                                                         MoreExecutors.directExecutor());
-
-            Futures.addCallback(dischargingFuture, new FutureCallback<>()
-            {
-                @Override
-                public void onSuccess(final Void result)
-                {
-                    doDelete();
-                }
-
-                @Override
-                public void onFailure(final Throwable t)
-                {
-                    _deleteQueueDepthFuture.setException(t);
-                }
-            }, MoreExecutors.directExecutor());
+            CompletableFuture<Void> dischargingFuture = CompletableFuture.allOf(dischargingTxs.toArray(CompletableFuture[]::new))
+                    .whenComplete((result, error) ->
+                    {
+                        if (error != null)
+                        {
+                            _deleteQueueDepthFuture.completeExceptionally(error);
+                        }
+                        else
+                        {
+                            doDelete();
+                        }
+                    });
         }
     }
 
@@ -2123,12 +2114,12 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         _stopped.set(true);
         _closing = false;
         _queueHouseKeepingTask.cancel();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -3285,17 +3276,17 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
     //=============
 
     @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         _virtualHost.scheduleHouseKeepingTask(_virtualHost.getHousekeepingCheckPeriod(), _queueHouseKeepingTask);
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
-        return Futures.transform(performDelete(), i -> null, getTaskExecutor());
+        return performDelete().thenApplyAsync(i -> null, getTaskExecutor());
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java b/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
index d9fa25872c..8a2a906374 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/queue/QueueConsumerImpl.java
@@ -28,12 +28,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -236,7 +235,7 @@ class QueueConsumerImpl<T extends ConsumerTarget>
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         if(_closed.compareAndSet(false,true))
         {
@@ -244,14 +243,13 @@ class QueueConsumerImpl<T extends ConsumerTarget>
 
             _waitingOnCreditMessageListener.remove();
 
-            return doAfter(_target.consumerRemoved(this),
-                           () -> {
-                               _queue.unregisterConsumer(QueueConsumerImpl.this);
-                           }).then(this::deleteNoChecks);
+            return _target.consumerRemoved(this)
+                    .thenRunAsync(() -> _queue.unregisterConsumer(QueueConsumerImpl.this), getTaskExecutor())
+                    .thenRunAsync(this::deleteNoChecks, getTaskExecutor());
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/queue/QueueFactory.java b/broker-core/src/main/java/org/apache/qpid/server/queue/QueueFactory.java
index 4995e936a5..11b94cf7ec 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/queue/QueueFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/queue/QueueFactory.java
@@ -21,8 +21,7 @@
 package org.apache.qpid.server.queue;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFactory;
@@ -51,9 +50,9 @@ public class QueueFactory<X extends Queue<X>>  implements ConfiguredObjectTypeFa
     }
 
     @Override
-    public ListenableFuture<X> createAsync(final ConfiguredObjectFactory factory,
-                                           final Map<String, Object> attributes,
-                                           final ConfiguredObject<?> parent)
+    public CompletableFuture<X> createAsync(final ConfiguredObjectFactory factory,
+                                            final Map<String, Object> attributes,
+                                            final ConfiguredObject<?> parent)
     {
         return getQueueFactory(factory, attributes).createAsync(factory, attributes, parent);
     }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java
index 3aeacba5a6..fb91bf8fac 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractKeyStore.java
@@ -29,12 +29,11 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -80,10 +79,10 @@ public abstract class AbstractKeyStore<X extends AbstractKeyStore<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         onCloseOrDelete();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     private void onCloseOrDelete()
@@ -158,7 +157,7 @@ public abstract class AbstractKeyStore<X extends AbstractKeyStore<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         onCloseOrDelete();
         return super.onDelete();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractTrustStore.java b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractTrustStore.java
index cab058ef93..3f5b2d9dc2 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/AbstractTrustStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/AbstractTrustStore.java
@@ -54,6 +54,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -64,8 +65,6 @@ import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
 import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.Outcome;
 import org.apache.qpid.server.transport.network.security.ssl.SSLUtil;
@@ -165,10 +164,10 @@ public abstract class AbstractTrustStore<X extends AbstractTrustStore<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         onCloseOrDelete();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -244,7 +243,7 @@ public abstract class AbstractTrustStore<X extends AbstractTrustStore<X>>
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         onCloseOrDelete();
         return super.onDelete();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/AllowAllAccessControlProviderImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/AllowAllAccessControlProviderImpl.java
index 5384ddbd07..0a0b1c711d 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/AllowAllAccessControlProviderImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/AllowAllAccessControlProviderImpl.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.security;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.logging.EventLogger;
 import org.apache.qpid.server.logging.Outcome;
@@ -75,20 +73,20 @@ public class AllowAllAccessControlProviderImpl extends AbstractConfiguredObject<
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
 
         setState(_broker.isManagementMode() ? State.QUIESCED : State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> startQuiesced()
+    private CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
index 1790b0e6fa..204e78c433 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/AutoGeneratedSelfSignedKeyStoreImpl.java
@@ -54,13 +54,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.bouncycastle.cert.CertIOException;
 import org.bouncycastle.operator.OperatorCreationException;
 
@@ -210,7 +209,7 @@ public class AutoGeneratedSelfSignedKeyStoreImpl
     }
 
     @StateTransition(currentState = { State.UNINITIALIZED, State.STOPPED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         if (!_created)
         {
@@ -218,7 +217,7 @@ public class AutoGeneratedSelfSignedKeyStoreImpl
         }
         setState(State.ACTIVE);
 
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     private void saveDerivedAttributesIfNecessary()
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
index 16c05801ab..3712a6bd1c 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileKeyStoreImpl.java
@@ -38,15 +38,13 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.X509KeyManager;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -104,11 +102,11 @@ public class FileKeyStoreImpl extends AbstractKeyStore<FileKeyStoreImpl> impleme
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
index 81738c696c..513c33cdaf 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/FileTrustStoreImpl.java
@@ -37,15 +37,13 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -102,11 +100,11 @@ public class FileTrustStoreImpl extends AbstractTrustStore<FileTrustStoreImpl> i
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStoreImpl.java
index 616fb2d6c8..5db1534237 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/ManagedPeerCertificateTrustStoreImpl.java
@@ -36,12 +36,11 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,11 +90,11 @@ public class ManagedPeerCertificateTrustStoreImpl
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @SuppressWarnings("unused")
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java
index 502227034c..d647338d97 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaKeyStoreImpl.java
@@ -44,6 +44,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
@@ -51,9 +52,6 @@ import javax.naming.ldap.Rdn;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -176,11 +174,11 @@ public class NonJavaKeyStoreImpl extends AbstractKeyStore<NonJavaKeyStoreImpl> i
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
index 32ebfd47fd..247f8e7f4e 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/NonJavaTrustStoreImpl.java
@@ -27,11 +27,10 @@ import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import javax.net.ssl.TrustManager;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,11 +101,11 @@ public class NonJavaTrustStoreImpl
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/SiteSpecificTrustStoreImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/SiteSpecificTrustStoreImpl.java
index b7aed8fc48..a279d0d6bd 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/SiteSpecificTrustStoreImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/SiteSpecificTrustStoreImpl.java
@@ -33,6 +33,7 @@ import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 
@@ -42,12 +43,9 @@ import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -167,34 +165,32 @@ public class SiteSpecificTrustStoreImpl
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
         initializeExpiryChecking();
 
-        final SettableFuture<Void> result = SettableFuture.create();
+        final CompletableFuture<Void> result = new CompletableFuture<>();
         if(_x509Certificate == null)
         {
             final String currentCertificate = getCertificate();
 
-            final ListenableFuture<X509Certificate> certFuture = downloadCertificate(getSiteUrl());
-            addFutureCallback(certFuture, new FutureCallback<>()
+            final CompletableFuture<X509Certificate> certFuture = downloadCertificate(getSiteUrl());
+            certFuture.whenCompleteAsync((result1, error) ->
             {
-                @Override
-                public void onSuccess(final X509Certificate cert)
-                {
-                    _x509Certificate = cert;
-                    attributeSet(CERTIFICATE, currentCertificate, _x509Certificate);
-                    generateTrustAndSetState(result);
-                }
-
-                @Override
-                public void onFailure(final Throwable t)
+                if (error != null)
                 {
                     _trustManagers = new TrustManager[0];
                     setState(State.ERRORED);
-                    result.setException(t);
+                    result.completeExceptionally(error);
+                }
+                else
+                {
+                    _x509Certificate = result1;
+                    attributeSet(CERTIFICATE, currentCertificate, _x509Certificate);
+                    generateTrustAndSetState(result);
                 }
             }, getTaskExecutor());
+
             return result;
         }
         else
@@ -204,33 +200,33 @@ public class SiteSpecificTrustStoreImpl
         return result;
     }
 
-    private void generateTrustAndSetState(final SettableFuture<Void> result)
+    private void generateTrustAndSetState(final CompletableFuture<Void> result)
     {
         State state = State.ERRORED;
         try
         {
             generateTrustManagers();
             state = State.ACTIVE;
-            result.set(null);
+            result.complete(null);
         }
         catch(IllegalConfigurationException e)
         {
-            result.setException(e);
+            result.completeExceptionally(e);
         }
         finally
         {
             setState(state);
-            result.set(null);
+            result.complete(null);
         }
     }
 
-    private ListenableFuture<X509Certificate> downloadCertificate(final String url)
+    private CompletableFuture<X509Certificate> downloadCertificate(final String url)
     {
         final ListeningExecutorService workerService = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(
                 getThreadFactory("download-certificate-worker-" + getName())));
         try
         {
-            return workerService.submit(() ->
+            return CompletableFuture.supplyAsync(() ->
             {
                 try
                 {
@@ -268,7 +264,7 @@ public class SiteSpecificTrustStoreImpl
                                                                           getName(),
                                                                           url), e);
                 }
-            });
+            }, workerService);
         }
         finally
         {
@@ -315,12 +311,12 @@ public class SiteSpecificTrustStoreImpl
     {
         logOperation("refreshCertificate");
         final String currentCertificate = getCertificate();
-        final ListenableFuture<X509Certificate> certFuture = downloadCertificate(getSiteUrl());
-        final ListenableFuture<Void> modelFuture = doAfter(certFuture, cert ->
+        final CompletableFuture<X509Certificate> certFuture = downloadCertificate(getSiteUrl());
+        final CompletableFuture<Void> modelFuture = certFuture.thenApply(cert ->
         {
             _x509Certificate = cert;
             attributeSet(CERTIFICATE, currentCertificate, _x509Certificate);
-            return Futures.immediateFuture(null);
+            return null;
         });
         doSync(modelFuture);
     }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/access/AbstractAccessControlProvider.java b/broker-core/src/main/java/org/apache/qpid/server/security/access/AbstractAccessControlProvider.java
index 096286a389..a74bf20956 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/access/AbstractAccessControlProvider.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/access/AbstractAccessControlProvider.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.security.access;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.logging.EventLogger;
 import org.apache.qpid.server.logging.EventLoggerProvider;
@@ -71,10 +69,10 @@ public abstract class AbstractAccessControlProvider<X extends AbstractAccessCont
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> startQuiesced()
+    private CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
index a9b4465ff7..1a1b085bde 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java
@@ -25,9 +25,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,14 +96,14 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica
 
 
     @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.QUIESCED )
-    protected ListenableFuture<Void> startQuiesced()
+    protected CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.QUIESCED }, desiredState = State.ACTIVE )
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         try
         {
@@ -122,7 +121,7 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica
                 throw e;
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
index ce433073f1..3f3f917064 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java
@@ -30,13 +30,12 @@ import java.util.Base64;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
 import javax.security.sasl.SaslException;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ManagedContextDefault;
@@ -76,7 +75,7 @@ public abstract class AbstractScramAuthenticationManager<X extends AbstractScram
 
     @Override
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.QUIESCED }, desiredState = State.ACTIVE )
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         _iterationCount = getContextValue(Integer.class, QPID_AUTHMANAGER_SCRAM_ITERATION_COUNT);
         for(ManagedUser user : getUserMap().values())
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java
index d595b0ae8a..6d80803d88 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java
@@ -28,13 +28,11 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 
 import javax.security.auth.login.AccountNotFoundException;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.configuration.updater.Task;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.Container;
@@ -218,10 +216,10 @@ public abstract class ConfigModelPasswordManagingAuthenticationProvider<X extend
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
-                                                                          final Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(final Class<C> childClass,
+                                                                              final Map<String, Object> attributes)
     {
-        if(childClass == User.class)
+        if (childClass == User.class)
         {
             String username = (String) attributes.get(User.NAME);
             if (_users.containsKey(username))
@@ -231,12 +229,10 @@ public abstract class ConfigModelPasswordManagingAuthenticationProvider<X extend
             attributes.put(User.PASSWORD, createStoredPassword((String) attributes.get(User.PASSWORD)));
             ManagedUser user = new ManagedUser(attributes, ConfigModelPasswordManagingAuthenticationProvider.this);
             user.create();
-            return Futures.immediateFuture((C)getUser(username));
-        }
-        else
-        {
-            return super.addChildAsync(childClass, attributes);
+            return CompletableFuture.completedFuture((C) getUser(username));
         }
+
+        return super.addChildAsync(childClass, attributes);
     }
 
     abstract void validateUser(final ManagedUser managedUser);
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ManagedUser.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ManagedUser.java
index fe2b440f19..8b023eb6bd 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ManagedUser.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ManagedUser.java
@@ -23,8 +23,7 @@ package org.apache.qpid.server.security.auth.manager;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.logging.Outcome;
 import org.apache.qpid.server.logging.messages.AuthenticationProviderMessages;
@@ -77,7 +76,7 @@ class ManagedUser extends AbstractConfiguredObject<ManagedUser> implements User<
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         _authenticationManager.getUserMap().remove(getName());
         return super.onDelete();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 5a18433d73..0e8da29f09 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -31,13 +31,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 
 import javax.security.auth.login.AccountNotFoundException;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -195,9 +193,9 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
 
     @Override
     @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
-    public ListenableFuture<Void> activate()
+    public CompletableFuture<Void> activate()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
+        final CompletableFuture<Void> returnVal = new CompletableFuture<>();
         final List<Principal> users = _principalDatabase == null ? List.of() : _principalDatabase.getUsers();
         _userMap.clear();
         if(!users.isEmpty())
@@ -206,13 +204,13 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
             {
                 final PrincipalAdapter principalAdapter = new PrincipalAdapter(user);
                 principalAdapter.registerWithParents();
-                principalAdapter.openAsync().addListener(() ->
+                principalAdapter.openAsync().whenCompleteAsync((result, error) ->
                 {
                     _userMap.put(user, principalAdapter);
                     if (_userMap.size() == users.size())
                     {
                         setState(State.ACTIVE);
-                        returnVal.set(null);
+                        returnVal.complete(null);
                     }
                 }, getTaskExecutor());
 
@@ -223,22 +221,22 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
         else
         {
             setState(State.ACTIVE);
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         // We manage the storage children so we close (so they may free any resources) them rather than deleting them
-        return doAfterAlways(closeChildren(),
-                             () -> {
-                                 File file = new File(_path);
-                                 if (file.exists() && file.isFile())
-                                 {
-                                     file.delete();
-                                 }
-                             });
+        return closeChildren().whenComplete((result, error) ->
+        {
+            final File file = new File(_path);
+            if (file.exists() && file.isFile())
+            {
+                file.delete();
+            }
+        });
     }
 
     @Override
@@ -305,8 +303,8 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
     }
 
     @Override
-    protected  <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                          Map<String, Object> attributes)
+    protected  <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                               Map<String, Object> attributes)
     {
         if(childClass == User.class)
         {
@@ -329,7 +327,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
                 throw e;
             }
             _userMap.put(p, principalAdapter);
-            return Futures.immediateFuture((C)principalAdapter);
+            return CompletableFuture.completedFuture((C)principalAdapter);
         }
         else
         {
@@ -438,14 +436,14 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
         }
 
         @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
-        private ListenableFuture<Void> activate()
+        private CompletableFuture<Void> activate()
         {
             setState(State.ACTIVE);
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
 
         @Override
-        protected ListenableFuture<Void> onDelete()
+        protected CompletableFuture<Void> onDelete()
         {
             try
             {
@@ -460,7 +458,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
         }
 
         @Override
-        protected ListenableFuture<Void> deleteNoChecks()
+        protected CompletableFuture<Void> deleteNoChecks()
         {
             return super.deleteNoChecks();
         }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupImpl.java
index 218f712948..63a862f053 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupImpl.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.security.group;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.Group;
@@ -47,9 +45,9 @@ public class GroupImpl extends AbstractConfiguredObject<GroupImpl> implements Gr
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupMemberImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupMemberImpl.java
index f5f99a6d35..c86befb8a4 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupMemberImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupMemberImpl.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.security.group;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -46,9 +44,9 @@ public class GroupMemberImpl extends AbstractConfiguredObject<GroupMemberImpl> i
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java
index 558225b783..585a03e362 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/group/GroupProviderImpl.java
@@ -25,9 +25,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractCaseAwareGroupProvider;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -75,8 +73,8 @@ public class GroupProviderImpl extends AbstractCaseAwareGroupProvider<GroupProvi
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
-                                                                             final Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(final Class<C> childClass,
+                                                                              final Map<String, Object> attributes)
     {
         if (childClass == Group.class)
         {
@@ -89,9 +87,9 @@ public class GroupProviderImpl extends AbstractCaseAwareGroupProvider<GroupProvi
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 }
diff --git a/broker-core/src/main/java/org/apache/qpid/server/security/group/cloudfoundry/CloudFoundryDashboardManagementGroupProviderImpl.java b/broker-core/src/main/java/org/apache/qpid/server/security/group/cloudfoundry/CloudFoundryDashboardManagementGroupProviderImpl.java
index b26a39781f..f4cc866c92 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/security/group/cloudfoundry/CloudFoundryDashboardManagementGroupProviderImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/security/group/cloudfoundry/CloudFoundryDashboardManagementGroupProviderImpl.java
@@ -40,11 +40,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -263,10 +263,10 @@ public class CloudFoundryDashboardManagementGroupProviderImpl extends AbstractCo
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/session/AMQPSession.java b/broker-core/src/main/java/org/apache/qpid/server/session/AMQPSession.java
index 11272146ac..b4260a1eba 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/session/AMQPSession.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/session/AMQPSession.java
@@ -20,7 +20,7 @@
  */
 package org.apache.qpid.server.session;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.consumer.ConsumerTarget;
 import org.apache.qpid.server.logging.EventLoggerProvider;
@@ -92,7 +92,7 @@ public interface AMQPSession<S extends org.apache.qpid.server.session.AMQPSessio
     @Override
     void close();
 
-    ListenableFuture<Void> doOnIOThreadAsync(final Runnable task);
+    CompletableFuture<Void> doOnIOThreadAsync(final Runnable task);
 
     void registerTransactedMessageReceived();
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/session/AbstractAMQPSession.java b/broker-core/src/main/java/org/apache/qpid/server/session/AbstractAMQPSession.java
index 4fd742e6e8..7f146bea42 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/session/AbstractAMQPSession.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/session/AbstractAMQPSession.java
@@ -27,6 +27,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -34,8 +35,6 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -199,7 +198,7 @@ public abstract class AbstractAMQPSession<S extends AbstractAMQPSession<S, X>,
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         removeDeleteTask(_deleteModelTask);
         return super.onDelete();
@@ -308,10 +307,10 @@ public abstract class AbstractAMQPSession<S extends AbstractAMQPSession<S, X>,
     public abstract boolean isClosing();
 
     @Override
-    public ListenableFuture<Void> doOnIOThreadAsync(final Runnable task)
+    public CompletableFuture<Void> doOnIOThreadAsync(final Runnable task)
     {
-        final ListenableFuture<Void> future = getAMQPConnection().doOnIOThreadAsync(task);
-        return doAfter(MoreExecutors.directExecutor(), future, () -> getAMQPConnection().notifyWork(AbstractAMQPSession.this));
+        return getAMQPConnection().doOnIOThreadAsync(task)
+                .whenComplete((result, error) -> getAMQPConnection().notifyWork(AbstractAMQPSession.this));
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
index bb13494c07..c44a026bdc 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
@@ -33,9 +33,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.message.EnqueueableMessage;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.store.handler.DistributedTransactionHandler;
diff --git a/broker-core/src/main/java/org/apache/qpid/server/transport/AMQPConnection.java b/broker-core/src/main/java/org/apache/qpid/server/transport/AMQPConnection.java
index 97fc81f243..fc17dda106 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/transport/AMQPConnection.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/transport/AMQPConnection.java
@@ -25,11 +25,10 @@ import java.security.AccessControlContext;
 import java.security.Principal;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.logging.EventLoggerProvider;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.Connection;
@@ -123,7 +122,7 @@ public interface AMQPConnection<C extends AMQPConnection<C>>
     void sendConnectionCloseAsync(CloseReason reason, String description);
 
     boolean isIOThread();
-    ListenableFuture<Void> doOnIOThreadAsync(final Runnable task);
+    CompletableFuture<Void> doOnIOThreadAsync(final Runnable task);
 
     void checkAuthorizedMessagePrincipal(String messageUserId);
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/transport/AbstractAMQPConnection.java b/broker-core/src/main/java/org/apache/qpid/server/transport/AbstractAMQPConnection.java
index 049c2e0b07..481420e941 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/transport/AbstractAMQPConnection.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/transport/AbstractAMQPConnection.java
@@ -35,6 +35,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicLong;
@@ -42,9 +43,6 @@ import java.util.concurrent.atomic.AtomicLong;
 import javax.security.auth.Subject;
 import javax.security.auth.SubjectDomainCombiner;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -105,8 +103,7 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
     private final long _connectionId;
     private final AggregateTicker _aggregateTicker;
     private final Subject _subject = new Subject();
-    private final List<Action<? super C>> _connectionCloseTaskList =
-            new CopyOnWriteArrayList<>();
+    private final List<Action<? super C>> _connectionCloseTaskList = new CopyOnWriteArrayList<>();
 
     private final LogSubject _logSubject;
     private volatile ContextProvider _contextProvider;
@@ -128,8 +125,8 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
     private final AtomicLong _localTransactionRollbacks = new AtomicLong();
     private final AtomicLong _localTransactionOpens = new AtomicLong();
 
-    private final SettableFuture<Void> _transportClosedFuture = SettableFuture.create();
-    private final SettableFuture<Void> _modelTransportRendezvousFuture = SettableFuture.create();
+    private final CompletableFuture<Void> _transportClosedFuture = new CompletableFuture<>();
+    private final CompletableFuture<Void> _modelTransportRendezvousFuture = new CompletableFuture<>();
     private volatile NamedAddressSpace _addressSpace;
     private volatile long _lastReadTime;
     private volatile long _lastWriteTime;
@@ -175,11 +172,11 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
 
         updateAccessControllerContext();
 
-        _transportClosedFuture.addListener(
-                () -> {
-                    _modelTransportRendezvousFuture.set(null);
-                    doAfter(closeAsync(), this::logConnectionClose);
-                }, getTaskExecutor());
+        _transportClosedFuture.thenRunAsync(() ->
+        {
+            _modelTransportRendezvousFuture.complete(null);
+            closeAsync().whenCompleteAsync((result, error) -> logConnectionClose(), getTaskExecutor());
+        }, getTaskExecutor());
 
         setState(State.ACTIVE);
         _logSubject = new ConnectionLogSubject(this);
@@ -527,27 +524,27 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
     }
 
     @Override
-    public ListenableFuture<Void> doOnIOThreadAsync(final Runnable task)
+    public CompletableFuture<Void> doOnIOThreadAsync(final Runnable task)
     {
         if (isIOThread())
         {
             task.run();
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
         else
         {
-            final SettableFuture<Void> future = SettableFuture.create();
+            final CompletableFuture<Void> future = new CompletableFuture<>();
 
             addAsyncTask(object ->
             {
                 try
                 {
                     task.run();
-                    future.set(null);
+                    future.complete(null);
                 }
                 catch (RuntimeException e)
                 {
-                    future.setException(e);
+                    future.completeExceptionally(e);
                 }
             });
             return future;
@@ -653,28 +650,28 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         return closeAsyncIfNotAlreadyClosing();
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         return closeAsyncIfNotAlreadyClosing();
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         if (_transactionObserver != null)
         {
             _transactionObserver.reset();
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
-    private ListenableFuture<Void> closeAsyncIfNotAlreadyClosing()
+    private CompletableFuture<Void> closeAsyncIfNotAlreadyClosing()
     {
         if (!_modelTransportRendezvousFuture.isDone())
         {
@@ -684,10 +681,10 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                          Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                              Map<String, Object> attributes)
     {
-        if(childClass == Session.class)
+        if (childClass == Session.class)
         {
             throw new IllegalStateException();
         }
@@ -695,7 +692,6 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
         {
             throw new IllegalArgumentException("Cannot create a child of class " + childClass.getSimpleName());
         }
-
     }
 
     @Override
@@ -833,7 +829,7 @@ public abstract class AbstractAMQPConnection<C extends AbstractAMQPConnection<C,
 
     protected void markTransportClosed()
     {
-        _transportClosedFuture.set(null);
+        _transportClosedFuture.complete(null);
     }
 
     public LogSubject getLogSubject()
diff --git a/broker-core/src/main/java/org/apache/qpid/server/transport/SelectorThread.java b/broker-core/src/main/java/org/apache/qpid/server/transport/SelectorThread.java
index 96144cbb3b..c96ab66246 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/transport/SelectorThread.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/transport/SelectorThread.java
@@ -35,6 +35,7 @@ import java.util.List;
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -44,7 +45,6 @@ import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -443,7 +443,7 @@ class SelectorThread extends Thread
 
     private Future<Void> cancelAcceptingSocketAsync(final ServerSocketChannel socketChannel)
     {
-        final SettableFuture<Void> cancellationResult = SettableFuture.create();
+        final CompletableFuture<Void> cancellationResult = new CompletableFuture<>();
         _tasks.add(() ->
         {
             if (LOGGER.isDebugEnabled())
@@ -472,7 +472,7 @@ class SelectorThread extends Thread
             }
             finally
             {
-                cancellationResult.set(null);
+                cancellationResult.complete(null);
             }
         });
         _selectionTasks[0].wakeup();
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractNonConnectionAcceptingVirtualHost.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractNonConnectionAcceptingVirtualHost.java
index b32dd49140..1abcdca0b5 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractNonConnectionAcceptingVirtualHost.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractNonConnectionAcceptingVirtualHost.java
@@ -25,10 +25,9 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.regex.Pattern;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.logging.messages.VirtualHostMessages;
 import org.apache.qpid.server.message.MessageDestination;
 import org.apache.qpid.server.message.MessageSource;
@@ -203,8 +202,8 @@ public abstract class AbstractNonConnectionAcceptingVirtualHost<X extends Abstra
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
-                                                                             final Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(final Class<C> childClass,
+                                                                              final Map<String, Object> attributes)
     {
         throwUnsupported();
         return null;
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
index 8391c1a9ad..5b8b8f9514 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
@@ -51,9 +51,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Future;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -67,12 +68,6 @@ import javax.security.auth.Subject;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -694,52 +689,49 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
 
     protected abstract MessageStore createMessageStore();
 
-    private ListenableFuture<List<Void>> createDefaultExchanges()
+    private CompletableFuture<Void> createDefaultExchanges()
     {
-        return Subject.doAs(getSubjectWithAddedSystemRights(), new PrivilegedAction<ListenableFuture<List<Void>>>()
+        return Subject.doAs(getSubjectWithAddedSystemRights(), new PrivilegedAction<CompletableFuture<Void>>()
         {
 
             @Override
-            public ListenableFuture<List<Void>> run()
+            public CompletableFuture<Void> run()
             {
-                List<ListenableFuture<Void>> standardExchangeFutures = new ArrayList<>();
+                List<CompletableFuture<Void>> standardExchangeFutures = new ArrayList<>();
                 standardExchangeFutures.add(addStandardExchange(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS));
                 standardExchangeFutures.add(addStandardExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS));
                 standardExchangeFutures.add(addStandardExchange(ExchangeDefaults.HEADERS_EXCHANGE_NAME, ExchangeDefaults.HEADERS_EXCHANGE_CLASS));
                 standardExchangeFutures.add(addStandardExchange(ExchangeDefaults.FANOUT_EXCHANGE_NAME, ExchangeDefaults.FANOUT_EXCHANGE_CLASS));
-                return Futures.allAsList(standardExchangeFutures);
+                return CompletableFuture.allOf(standardExchangeFutures.toArray(CompletableFuture[]::new));
             }
 
-            ListenableFuture<Void> addStandardExchange(String name, String type)
+            CompletableFuture<Void> addStandardExchange(String name, String type)
             {
 
                 Map<String, Object> attributes = new HashMap<>();
                 attributes.put(Exchange.NAME, name);
                 attributes.put(Exchange.TYPE, type);
                 attributes.put(Exchange.ID, UUIDGenerator.generateExchangeUUID(name, getName()));
-                final ListenableFuture<Exchange<?>> future = addExchangeAsync(attributes);
-                final SettableFuture<Void> returnVal = SettableFuture.create();
-                addFutureCallback(future, new FutureCallback<>()
+                final CompletableFuture<Exchange<?>> future = addExchangeAsync(attributes);
+                final CompletableFuture<Void> returnVal = new CompletableFuture<>();
+                future.whenCompleteAsync((result, throwable) ->
                 {
-                    @Override
-                    public void onSuccess(final Exchange<?> result)
+                    if (throwable != null)
+                    {
+                        returnVal.completeExceptionally(throwable);
+                    }
+                    else
                     {
                         try
                         {
                             childAdded(result);
-                            returnVal.set(null);
+                            returnVal.complete(null);
                         }
                         catch (Throwable t)
                         {
-                            returnVal.setException(t);
+                            returnVal.completeExceptionally(t);
                         }
                     }
-
-                    @Override
-                    public void onFailure(final Throwable t)
-                    {
-                        returnVal.setException(t);
-                    }
                 }, getTaskExecutor());
 
                 return returnVal;
@@ -860,7 +852,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
                                                                              Map<String, Object> attributes)
     {
         checkVHostStateIsActive();
@@ -877,15 +869,15 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public Map<String, Object> extractConfig(final boolean includeSecureAttributes)
     {
-        return doSync(doOnConfigThread(new Task<ListenableFuture<Map<String,Object>>, RuntimeException>()
+        return doSync(doOnConfigThread(new Task<CompletableFuture<Map<String,Object>>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Map<String, Object>> execute() throws RuntimeException
+            public CompletableFuture<Map<String, Object>> execute() throws RuntimeException
             {
                 ConfigurationExtractor configExtractor = new ConfigurationExtractor();
                 Map<String, Object> config = configExtractor.extractConfig(AbstractVirtualHost.this,
                                                                            includeSecureAttributes);
-                return Futures.immediateFuture(config);
+                return CompletableFuture.completedFuture(config);
             }
 
             @Override
@@ -920,10 +912,10 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
         @Override
         public void write(final OutputStream outputStream) throws IOException
         {
-            doSync(doOnConfigThread(new Task<ListenableFuture<Void>, IOException>()
+            doSync(doOnConfigThread(new Task<CompletableFuture<Void>, IOException>()
             {
                 @Override
-                public ListenableFuture<Void> execute() throws IOException
+                public CompletableFuture<Void> execute() throws IOException
                 {
                     if (getState() != State.STOPPED)
                     {
@@ -950,7 +942,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                     {
                         _messageStore.closeMessageStore();
                     }
-                    return Futures.immediateFuture(null);
+                    return CompletableFuture.completedFuture(null);
                 }
 
                 @Override
@@ -1025,10 +1017,10 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
 
                 final MessageStoreSerializer serializer = MessageStoreSerializer.FACTORY.newInstance(data);
 
-                doSync(doOnConfigThread(new Task<ListenableFuture<Void>, IOException>()
+                doSync(doOnConfigThread(new Task<CompletableFuture<Void>, IOException>()
                 {
                     @Override
-                    public ListenableFuture<Void> execute() throws IOException
+                    public CompletableFuture<Void> execute() throws IOException
                     {
                         if (getState() != State.STOPPED)
                         {
@@ -1056,7 +1048,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                         {
                             _messageStore.closeMessageStore();
                         }
-                        return Futures.immediateFuture(null);
+                        return CompletableFuture.completedFuture(null);
                     }
 
                     @Override
@@ -1398,27 +1390,25 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @Override
-    public ListenableFuture<Void> reallocateMessages()
+    public CompletableFuture<Void> reallocateMessages()
     {
         final ScheduledThreadPoolExecutor houseKeepingTaskExecutor = _houseKeepingTaskExecutor;
         if (houseKeepingTaskExecutor != null)
         {
             try
             {
-                final Future<Void> future = houseKeepingTaskExecutor.submit(() ->
-                                                                            {
-                                                                                final Collection<Queue> queues =
-                                                                                        getChildren(Queue.class);
-                                                                                for (Queue q : queues)
-                                                                                {
-                                                                                    if (q.getState() == State.ACTIVE)
-                                                                                    {
-                                                                                        q.reallocateMessages();
-                                                                                    }
-                                                                                }
-                                                                                return null;
-                                                                            });
-                return JdkFutureAdapters.listenInPoolThread(future);
+                return CompletableFuture.runAsync(() ->
+                                           {
+                                               final Collection<Queue> queues =
+                                                       getChildren(Queue.class);
+                                               for (Queue q : queues)
+                                               {
+                                                   if (q.getState() == State.ACTIVE)
+                                                   {
+                                                       q.reallocateMessages();
+                                                   }
+                                               }
+                                           }, houseKeepingTaskExecutor);
             }
             catch (RejectedExecutionException e)
             {
@@ -1428,7 +1418,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                 }
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -1527,28 +1517,24 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
         getChildren(Exchange.class).forEach(Exchange::resetStatistics);
     }
 
-    private ListenableFuture<Exchange<?>> addExchangeAsync(Map<String,Object> attributes)
+    private CompletableFuture<Exchange<?>> addExchangeAsync(Map<String,Object> attributes)
             throws ReservedExchangeNameException,
                    NoFactoryForTypeException
     {
-        final SettableFuture<Exchange<?>> returnVal = SettableFuture.create();
-        addFutureCallback(getObjectFactory().createAsync(Exchange.class, attributes, this),
-                            new FutureCallback<Exchange>()
-                            {
-                                @Override
-                                public void onSuccess(final Exchange result)
-                                {
-                                    returnVal.set(result);
-                                }
+        final CompletableFuture<Exchange<?>> returnVal = new CompletableFuture<>();
+        getObjectFactory().createAsync(Exchange.class, attributes, this).whenCompleteAsync((result, throwable) ->
+        {
+            if (throwable != null)
+            {
+                returnVal.completeExceptionally((Throwable) throwable);
+            }
+            else
+            {
+                returnVal.complete((Exchange<?>) result);
+            }
+        }, getTaskExecutor());
 
-                              @Override
-                              public void onFailure(final Throwable t)
-                              {
-                                  returnVal.setException(t);
-                              }
-                          }, getTaskExecutor());
         return returnVal;
-
     }
 
     @Override
@@ -1568,31 +1554,31 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         return beforeDeleteOrClose();
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         return onCloseOrDelete();
     }
 
     @Override
-    protected ListenableFuture<Void> beforeDelete()
+    protected CompletableFuture<Void> beforeDelete()
     {
         return beforeDeleteOrClose();
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         _deleteRequested  = true;
         return onCloseOrDelete();
     }
 
-    private ListenableFuture<Void> beforeDeleteOrClose()
+    private CompletableFuture<Void> beforeDeleteOrClose()
     {
         setState(State.UNAVAILABLE);
         _virtualHostLoggersToClose = new ArrayList<>(getChildren(VirtualHostLogger.class));
@@ -1600,7 +1586,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
         return closeConnections();
     }
 
-    private ListenableFuture<Void> onCloseOrDelete()
+    private CompletableFuture<Void> onCloseOrDelete()
     {
         _dtxRegistry.close();
         shutdownHouseKeeping();
@@ -1627,11 +1613,11 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
         _systemNodeRegistry.close();
 
         closeConnectionLimiter();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 
-    private ListenableFuture<Void> closeConnections()
+    private CompletableFuture<Void> closeConnections()
     {
         if (LOGGER.isDebugEnabled())
         {
@@ -1643,7 +1629,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
             conn.stopConnection();
         }
 
-        List<ListenableFuture<Void>> connectionCloseFutures = new ArrayList<>();
+        List<CompletableFuture<Void>> connectionCloseFutures = new ArrayList<>();
         while (!_connections.isEmpty())
         {
             Iterator<AMQPConnection<?>> itr = _connections.iterator();
@@ -1664,8 +1650,8 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                 }
             }
         }
-        ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(connectionCloseFutures);
-        return Futures.transform(combinedFuture, voids -> null, MoreExecutors.directExecutor());
+        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(connectionCloseFutures.toArray(CompletableFuture[]::new));
+        return combinedFuture.thenApply(voids -> null);
     }
 
     private void closeMessageStore()
@@ -1770,12 +1756,12 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public <T extends LinkModel> T getSendingLink( String remoteContainerId, String linkName)
     {
-        return doSync(doOnConfigThread(new Task<ListenableFuture<T>, RuntimeException>()
+        return doSync(doOnConfigThread(new Task<CompletableFuture<T>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<T> execute()
+            public CompletableFuture<T> execute()
             {
-                return Futures.immediateFuture((T)_linkRegistry.getSendingLink(remoteContainerId, linkName));
+                return CompletableFuture.completedFuture((T)_linkRegistry.getSendingLink(remoteContainerId, linkName));
             }
 
             @Override
@@ -1801,12 +1787,12 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public <T extends LinkModel> T getReceivingLink(String remoteContainerId, String linkName)
     {
-        return doSync(doOnConfigThread(new Task<ListenableFuture<T>, RuntimeException>()
+        return doSync(doOnConfigThread(new Task<CompletableFuture<T>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<T> execute()
+            public CompletableFuture<T> execute()
             {
-                return Futures.immediateFuture((T)_linkRegistry.getReceivingLink(remoteContainerId, linkName));
+                return CompletableFuture.completedFuture((T)_linkRegistry.getReceivingLink(remoteContainerId, linkName));
             }
 
             @Override
@@ -1833,12 +1819,12 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     public <T extends LinkModel> Collection<T> findSendingLinks(final Pattern containerIdPattern,
                                                                 final Pattern linkNamePattern)
     {
-        return doSync(doOnConfigThread(new Task<ListenableFuture<Collection<T>>, RuntimeException>()
+        return doSync(doOnConfigThread(new Task<CompletableFuture<Collection<T>>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Collection<T>> execute()
+            public CompletableFuture<Collection<T>> execute()
             {
-                return Futures.immediateFuture(_linkRegistry.findSendingLinks(containerIdPattern, linkNamePattern));
+                return CompletableFuture.completedFuture(_linkRegistry.findSendingLinks(containerIdPattern, linkNamePattern));
             }
 
             @Override
@@ -1864,13 +1850,13 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public <T extends LinkModel> void visitSendingLinks(final LinkRegistryModel.LinkVisitor<T> visitor)
     {
-        doSync(doOnConfigThread(new Task<ListenableFuture<Void>, RuntimeException>()
+        doSync(doOnConfigThread(new Task<CompletableFuture<Void>, RuntimeException>()
         {
             @Override
-            public ListenableFuture<Void> execute()
+            public CompletableFuture<Void> execute()
             {
                 _linkRegistry.visitSendingLinks(visitor);
-                return Futures.immediateFuture(null);
+                return CompletableFuture.completedFuture(null);
             }
 
             @Override
@@ -2442,10 +2428,10 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @StateTransition( currentState = { State.UNINITIALIZED, State.ACTIVE, State.ERRORED }, desiredState = State.STOPPED )
-    protected ListenableFuture<Void> doStop()
+    protected CompletableFuture<Void> doStop()
     {
         final List<VirtualHostLogger> loggers = new ArrayList<>(getChildren(VirtualHostLogger.class));
-        return doAfter(closeConnections(), () -> closeChildren()).then(() ->
+        return closeConnections().thenApplyAsync(result -> closeChildren(), getTaskExecutor()).thenRunAsync(() ->
         {
             shutdownHouseKeeping();
             closeNetworkConnectionScheduler();
@@ -2459,7 +2445,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
             setState(State.STOPPED);
             stopLogging(loggers);
             closeConnectionLimiter();
-        });
+        }, getTaskExecutor());
     }
 
     @Override
@@ -2620,7 +2606,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
-    private ListenableFuture<Void> onActivate()
+    private CompletableFuture<Void> onActivate()
     {
 
         long threadPoolKeepAliveTimeout = getContextValue(Long.class, CONNECTION_THREAD_POOL_KEEP_ALIVE_TIMEOUT);
@@ -2671,16 +2657,16 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
 
         if (_createDefaultExchanges)
         {
-            return doAfter(createDefaultExchanges(), () ->
+            return createDefaultExchanges().thenRunAsync(() ->
             {
                 _createDefaultExchanges = false;
                 postCreateDefaultExchangeTasks();
-            });
+            }, getTaskExecutor());
         }
         else
         {
             postCreateDefaultExchangeTasks();
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
@@ -2697,8 +2683,18 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
 
         // propagate any exception thrown during recovery into HouseKeepingTaskExecutor to handle them accordingly
         // TODO if message recovery fails we ought to be transitioning the VH into ERROR and releasing the thread-pools etc.
-        final ListenableFuture<Void> recoveryResult = _messageStoreRecoverer.recover(this);
-        recoveryResult.addListener(() -> Futures.getUnchecked(recoveryResult), _houseKeepingTaskExecutor);
+        final CompletableFuture<Void> recoveryResult = _messageStoreRecoverer.recover(this);
+        recoveryResult.whenCompleteAsync((result, throwable) ->
+        {
+            try
+            {
+                recoveryResult.get();
+            }
+            catch (InterruptedException | ExecutionException e)
+            {
+                // do nothing
+            }
+        }, _houseKeepingTaskExecutor);
 
         State finalState = State.ERRORED;
         try
@@ -2740,35 +2736,31 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     }
 
     @StateTransition( currentState = { State.STOPPED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> onRestart()
+    private CompletableFuture<Void> onRestart()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
+        final CompletableFuture<Void> returnVal = new CompletableFuture<>();
         try
         {
-            addFutureCallback(doRestart(), new FutureCallback<>()
-                              {
-                                  @Override
-                                  public void onSuccess(final Void result)
-                                  {
-                                      returnVal.set(null);
-                                  }
-
-                                  @Override
-                                  public void onFailure(final Throwable t)
-                                  {
-                                      doAfterAlways(onRestartFailure(), () -> returnVal.setException(t));
-                                  }
-                              }, getTaskExecutor()
-                             );
+            doRestart().whenCompleteAsync((result, throwable) ->
+            {
+                if (throwable != null)
+                {
+                    onRestartFailure().whenComplete((result1, throwable1) -> returnVal.completeExceptionally(throwable));
+                }
+                else
+                {
+                    returnVal.complete(null);
+                }
+                }, getTaskExecutor());
         }
         catch (IllegalArgumentException | IllegalConfigurationException e)
         {
-            doAfterAlways(onRestartFailure(), ()-> returnVal.setException(e));
+            onRestartFailure().whenComplete((result, throwable) -> returnVal.completeExceptionally(e));
         }
         return returnVal;
     }
 
-    private ListenableFuture<Void> doRestart()
+    private CompletableFuture<Void> doRestart()
     {
         createHousekeepingExecutor();
 
@@ -2782,27 +2774,20 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
             accessControlProviders.forEach(child -> child.addChangeListener(_accessControlProviderListener));
         }
 
-        final List<ListenableFuture<Void>> childOpenFutures = new ArrayList<>();
+        final List<CompletableFuture<Void>> childOpenFutures = new ArrayList<>();
 
         Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<Object>) () ->
         {
             applyToChildren(child ->
                             {
-                                final ListenableFuture<Void> childOpenFuture = child.openAsync();
+                                final CompletableFuture<Void> childOpenFuture = child.openAsync();
                                 childOpenFutures.add(childOpenFuture);
-
-                                addFutureCallback(childOpenFuture, new FutureCallback<>()
+                                childOpenFuture.whenCompleteAsync((result, throwable) ->
                                 {
-                                    @Override
-                                    public void onSuccess(final Void result)
-                                    {
-                                    }
-
-                                    @Override
-                                    public void onFailure(final Throwable t)
+                                    if (throwable != null)
                                     {
                                         LOGGER.error("Exception occurred while opening {} : {}",
-                                                     child.getClass().getSimpleName(), child.getName(), t);
+                                                     child.getClass().getSimpleName(), child.getName(), throwable);
                                         onRestartFailure();
                                     }
                                 }, getTaskExecutor());
@@ -2810,14 +2795,15 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
             return null;
         });
 
-        ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(childOpenFutures);
-        return Futures.transformAsync(combinedFuture, input -> onActivate(), MoreExecutors.directExecutor());
+        CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(childOpenFutures.toArray(CompletableFuture[]::new));
+        return combinedFuture.thenAccept(result -> onActivate());
     }
 
-    private ChainedListenableFuture<Void> onRestartFailure()
+    private CompletableFuture<Void> onRestartFailure()
     {
         final List<VirtualHostLogger> loggers = new ArrayList<>(getChildren(VirtualHostLogger.class));
-        return doAfter(closeChildren(), () -> {
+        return closeChildren().thenRunAsync(() ->
+        {
             shutdownHouseKeeping();
             closeNetworkConnectionScheduler();
             if (_linkRegistry != null)
@@ -2830,7 +2816,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
             setState(State.ERRORED);
             stopLogging(loggers);
             closeConnectionLimiter();
-        });
+        }, getTaskExecutor());
     }
 
     private class FileSystemSpaceChecker extends HouseKeepingTask
@@ -3026,10 +3012,10 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public Object dumpLinkRegistry()
     {
-        return doSync(doOnConfigThread(new Task<ListenableFuture<Object>, IOException>()
+        return doSync(doOnConfigThread(new Task<CompletableFuture<Object>, IOException>()
         {
             @Override
-            public ListenableFuture<Object> execute() throws IOException
+            public CompletableFuture<Object> execute() throws IOException
             {
                 Object dump;
                 if (getState() == State.STOPPED)
@@ -3060,7 +3046,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                 {
                     throw new IllegalStateException("The dumpLinkRegistry operation can only be called when the virtual host is active or stopped.");
                 }
-                return Futures.immediateFuture(dump);
+                return CompletableFuture.completedFuture(dump);
             }
 
             @Override
@@ -3086,10 +3072,10 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
     @Override
     public void purgeLinkRegistry(final String containerIdPatternString, final String role, final String linkNamePatternString)
     {
-        doSync(doOnConfigThread(new Task<ListenableFuture<Void>, IOException>()
+        doSync(doOnConfigThread(new Task<CompletableFuture<Void>, IOException>()
         {
             @Override
-            public ListenableFuture<Void> execute() throws IOException
+            public CompletableFuture<Void> execute() throws IOException
             {
                 if (getState() != State.STOPPED)
                 {
@@ -3113,7 +3099,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
                         {
                             _linkRegistry.purgeReceivingLinks(containerIdPattern, linkNamePattern);
                         }
-                        return Futures.immediateFuture(null);
+                        return CompletableFuture.completedFuture(null);
                     }
                     finally
                     {
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecoverer.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecoverer.java
index dc810497c5..e1f3a7a5c0 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecoverer.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecoverer.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.Executors;
 import java.util.concurrent.SynchronousQueue;
@@ -33,8 +34,6 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import org.slf4j.Logger;
@@ -69,7 +68,7 @@ public class AsynchronousMessageStoreRecoverer implements MessageStoreRecoverer
     private AsynchronousRecoverer _asynchronousRecoverer;
 
     @Override
-    public ListenableFuture<Void> recover(final QueueManagingVirtualHost<?> virtualHost)
+    public CompletableFuture<Void> recover(final QueueManagingVirtualHost<?> virtualHost)
     {
         _asynchronousRecoverer = new AsynchronousRecoverer(virtualHost);
 
@@ -121,24 +120,24 @@ public class AsynchronousMessageStoreRecoverer implements MessageStoreRecoverer
 
         }
 
-        public ListenableFuture<Void> recover()
+        public CompletableFuture<Void> recover()
         {
             getStoreReader().visitDistributedTransactions(new DistributedTransactionVisitor());
 
-            List<ListenableFuture<Void>> queueRecoveryFutures = new ArrayList<>();
-            if(_recoveringQueues.isEmpty())
+            List<CompletableFuture<Void>> queueRecoveryFutures = new ArrayList<>();
+            if (_recoveringQueues.isEmpty())
             {
-                return _queueRecoveryExecutor.submit(new RemoveOrphanedMessagesTask(), null);
+                return CompletableFuture.runAsync(new RemoveOrphanedMessagesTask(), _queueRecoveryExecutor);
             }
             else
             {
                 for (Queue<?> queue : _recoveringQueues)
                 {
-                    ListenableFuture<Void> result = _queueRecoveryExecutor.submit(new QueueRecoveringTask(queue), null);
+                    CompletableFuture<Void> result = CompletableFuture.runAsync(new QueueRecoveringTask(queue), _queueRecoveryExecutor);
                     queueRecoveryFutures.add(result);
                 }
-                ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(queueRecoveryFutures);
-                return Futures.transform(combinedFuture, voids -> null, MoreExecutors.directExecutor());
+                CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(queueRecoveryFutures.toArray(CompletableFuture[]::new));
+                return combinedFuture.thenApply(voids -> null);
             }
         }
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/MessageStoreRecoverer.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/MessageStoreRecoverer.java
index 107a7b5700..5d7255521b 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/MessageStoreRecoverer.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/MessageStoreRecoverer.java
@@ -20,11 +20,11 @@
  */
 package org.apache.qpid.server.virtualhost;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 public interface MessageStoreRecoverer
 {
-    ListenableFuture<Void> recover(QueueManagingVirtualHost<?> virtualHost);
+    CompletableFuture<Void> recover(QueueManagingVirtualHost<?> virtualHost);
 
     /**
      * Cancels any in-progress message store recovery.  If message store recovery has already
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
index 21534d8a12..00a9122819 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueManagingVirtualHost.java
@@ -25,10 +25,9 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ScheduledFuture;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.logging.EventLoggerProvider;
 import org.apache.qpid.server.message.MessageDestination;
 import org.apache.qpid.server.model.Broker;
@@ -401,7 +400,7 @@ public interface QueueManagingVirtualHost<X extends QueueManagingVirtualHost<X>>
 
     MessageDestination getSystemDestination(String name);
 
-    ListenableFuture<Void> reallocateMessages();
+    CompletableFuture<Void> reallocateMessages();
 
     boolean isOverTargetSize();
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/SynchronousMessageStoreRecoverer.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/SynchronousMessageStoreRecoverer.java
index 9181859c70..b71735f7d1 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhost/SynchronousMessageStoreRecoverer.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhost/SynchronousMessageStoreRecoverer.java
@@ -24,9 +24,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,7 +59,7 @@ public class SynchronousMessageStoreRecoverer implements MessageStoreRecoverer
     private static final Logger LOGGER = LoggerFactory.getLogger(SynchronousMessageStoreRecoverer.class);
 
     @Override
-    public ListenableFuture<Void> recover(QueueManagingVirtualHost<?> virtualHost)
+    public CompletableFuture<Void> recover(QueueManagingVirtualHost<?> virtualHost)
     {
         EventLogger eventLogger = virtualHost.getEventLogger();
         MessageStore store = virtualHost.getMessageStore();
@@ -146,7 +145,7 @@ public class SynchronousMessageStoreRecoverer implements MessageStoreRecoverer
                              MessageStoreMessages.RECOVERED(recoveredMessages.size() - unusedMessages.size()));
         eventLogger.message(logSubject, MessageStoreMessages.RECOVERY_COMPLETE());
 
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
index ed10107df3..74972c5552 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
@@ -26,11 +26,10 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,7 +61,7 @@ public abstract class AbstractStandardVirtualHostNode<X extends AbstractStandard
     }
 
     @Override
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         if (LOGGER.isDebugEnabled())
         {
@@ -103,48 +102,48 @@ public abstract class AbstractStandardVirtualHostNode<X extends AbstractStandard
         if (host != null)
         {
             final QueueManagingVirtualHost<?> recoveredHost = host;
-            final ListenableFuture<Void> openFuture;
+            final CompletableFuture<Void> openFuture;
             recoveredHost.setFirstOpening(isNew && initialRecords.length == 0);
-            openFuture = Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<ListenableFuture<Void>>) recoveredHost::openAsync);
+            openFuture = Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<CompletableFuture<Void>>) recoveredHost::openAsync);
             return openFuture;
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         final VirtualHost<?> virtualHost = getVirtualHost();
         final MessageStore messageStore = virtualHost == null ? null : virtualHost.getMessageStore();
 
-        return doAfterAlways(closeVirtualHostIfExists(),
-                             () -> {
-                                 if (messageStore != null)
-                                 {
-                                     messageStore.closeMessageStore();
-                                     messageStore.onDelete(virtualHost);
-                                 }
-
-                                 if (AbstractStandardVirtualHostNode.this instanceof PreferenceStoreProvider)
-                                 {
-                                     PreferenceStore preferenceStore =
-                                             ((PreferenceStoreProvider) AbstractStandardVirtualHostNode.this).getPreferenceStore();
-                                     if (preferenceStore != null)
-                                     {
-                                         preferenceStore.onDelete();
-                                     }
-                                 }
-                                 DurableConfigurationStore configurationStore = getConfigurationStore();
-                                 if (configurationStore != null)
-                                 {
-                                     configurationStore.closeConfigurationStore();
-                                     configurationStore.onDelete(AbstractStandardVirtualHostNode.this);
-                                 }
-                                 onCloseOrDelete();
-                             });
+        return closeVirtualHostIfExists().whenComplete((result, error) ->
+        {
+            if (messageStore != null)
+            {
+                messageStore.closeMessageStore();
+                messageStore.onDelete(virtualHost);
+            }
+
+            if (AbstractStandardVirtualHostNode.this instanceof PreferenceStoreProvider)
+            {
+                PreferenceStore preferenceStore =
+                        ((PreferenceStoreProvider) AbstractStandardVirtualHostNode.this).getPreferenceStore();
+                if (preferenceStore != null)
+                {
+                    preferenceStore.onDelete();
+                }
+            }
+            DurableConfigurationStore configurationStore = getConfigurationStore();
+            if (configurationStore != null)
+            {
+                configurationStore.closeConfigurationStore();
+                configurationStore.onDelete(AbstractStandardVirtualHostNode.this);
+            }
+            onCloseOrDelete();
+        });
     }
 
     @Override
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
index 857976f203..576a7948bf 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
@@ -36,11 +36,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -153,42 +150,37 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
     }
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
-    protected ListenableFuture<Void> startQuiesced()
+    protected CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @StateTransition( currentState = {State.UNINITIALIZED, State.STOPPED, State.ERRORED }, desiredState = State.ACTIVE )
-    protected ListenableFuture<Void> doActivate()
+    protected CompletableFuture<Void> doActivate()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
+        final CompletableFuture<Void> returnVal = new CompletableFuture<>();
 
         try
         {
-            addFutureCallback(activate(),
-                              new FutureCallback<>()
-                              {
-                                  @Override
-                                  public void onSuccess(final Void result)
-                                  {
-                                      try
-                                      {
-                                          setState(State.ACTIVE);
-                                      }
-                                      finally
-                                      {
-                                          returnVal.set(null);
-                                      }
-                                  }
-
-                                  @Override
-                                  public void onFailure(final Throwable t)
-                                  {
-                                      onActivationFailure(returnVal, t);
-                                  }
-                              }, getTaskExecutor()
-                               );
+            activate().whenCompleteAsync((result, throwable) ->
+            {
+                if (throwable != null)
+                {
+                    onActivationFailure(returnVal, throwable);
+                }
+                else
+                {
+                    try
+                    {
+                        setState(State.ACTIVE);
+                    }
+                    finally
+                    {
+                        returnVal.complete(null);
+                    }
+                }
+            }, getTaskExecutor());
         }
         catch(RuntimeException e)
         {
@@ -197,17 +189,18 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
         return returnVal;
     }
 
-    private void onActivationFailure(final SettableFuture<Void> returnVal, final Throwable e)
+    private void onActivationFailure(final CompletableFuture<Void> returnVal, final Throwable e)
     {
-        doAfterAlways(stopAndSetStateTo(State.ERRORED), () -> {
+        stopAndSetStateTo(State.ERRORED).whenComplete((throwable, error) ->
+        {
             if (_broker.isManagementMode())
             {
                 LOGGER.warn("Failed to make " + this + " active.", e);
-                returnVal.set(null);
+                returnVal.complete(null);
             }
             else
             {
-                returnVal.setException(e);
+                returnVal.completeExceptionally(e);
             }
         });
     }
@@ -289,12 +282,12 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         throw new UnsupportedOperationException("Sub-classes must override");
     }
 
-    protected ListenableFuture<Void> closeVirtualHostIfExists()
+    protected CompletableFuture<Void> closeVirtualHostIfExists()
     {
         final VirtualHost<?> virtualHost = getVirtualHost();
         if (virtualHost != null)
@@ -303,20 +296,20 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
         }
         else
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @StateTransition( currentState = { State.ACTIVE, State.ERRORED, State.UNINITIALIZED }, desiredState = State.STOPPED )
-    protected ListenableFuture<Void> doStop()
+    protected CompletableFuture<Void> doStop()
     {
         return stopAndSetStateTo(State.STOPPED);
     }
 
-    protected ListenableFuture<Void> stopAndSetStateTo(final State stoppedState)
+    protected CompletableFuture<Void> stopAndSetStateTo(final State stoppedState)
     {
-        ListenableFuture<Void> childCloseFuture = closeChildren();
-        return doAfterAlways(childCloseFuture, () ->
+        CompletableFuture<Void> childCloseFuture = closeChildren();
+        return childCloseFuture.whenComplete((result, throwable) ->
         {
             closeConfigurationStoreSafely();
             setState(stoppedState);
@@ -343,11 +336,11 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         closeConfigurationStore();
         onCloseOrDelete();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     protected void onCloseOrDelete()
@@ -419,7 +412,7 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
 
     protected abstract DurableConfigurationStore createConfigurationStore();
 
-    protected abstract ListenableFuture<Void> activate();
+    protected abstract CompletableFuture<Void> activate();
 
     protected abstract ConfiguredObjectRecord enrichInitialVirtualHostRootRecord(final ConfiguredObjectRecord vhostRecord);
 
diff --git a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/RedirectingVirtualHostNodeImpl.java b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/RedirectingVirtualHostNodeImpl.java
index 8aff03f78c..dcf12b53bc 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/RedirectingVirtualHostNodeImpl.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/RedirectingVirtualHostNodeImpl.java
@@ -25,11 +25,8 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -80,56 +77,54 @@ public class RedirectingVirtualHostNodeImpl
     }
 
     @StateTransition( currentState = {State.UNINITIALIZED, State.STOPPED, State.ERRORED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> doActivate()
+    private CompletableFuture<Void> doActivate()
     {
-        final SettableFuture<Void> resultFuture = SettableFuture.create();
+        final CompletableFuture<Void> resultFuture = new CompletableFuture<>();
         Map<String, Object> attributes = new HashMap<>();
         attributes.put(ConfiguredObject.NAME, getName());
         attributes.put(ConfiguredObject.TYPE, RedirectingVirtualHostImpl.VIRTUAL_HOST_TYPE);
 
-        final ListenableFuture<VirtualHost> virtualHostFuture = getObjectFactory().createAsync(VirtualHost.class, attributes, this);
+        final CompletableFuture<VirtualHost>
+                virtualHostFuture = getObjectFactory().createAsync(VirtualHost.class, attributes, this);
 
-        addFutureCallback(virtualHostFuture, new FutureCallback<>()
+        virtualHostFuture.whenCompleteAsync((result, error) ->
         {
-            @Override
-            public void onSuccess(final VirtualHost virtualHost)
-            {
-                _virtualHost = (RedirectingVirtualHostImpl) virtualHost;
-                setState(State.ACTIVE);
-                resultFuture.set(null);
-            }
-
-            @Override
-            public void onFailure(final Throwable t)
+            if (error != null)
             {
                 setState(State.ERRORED);
                 if (((Broker) getParent()).isManagementMode())
                 {
-                    LOGGER.warn("Failed to make {} active.", this, t);
-                    resultFuture.set(null);
+                    LOGGER.warn("Failed to make {} active.", this, error);
+                    resultFuture.complete(null);
                 }
                 else
                 {
-                    resultFuture.setException(t);
+                    resultFuture.completeExceptionally(error);
                 }
             }
+            else
+            {
+                _virtualHost = (RedirectingVirtualHostImpl) result;
+                setState(State.ACTIVE);
+                resultFuture.complete(null);
+            }
         }, getTaskExecutor());
 
         return resultFuture;
     }
 
     @StateTransition( currentState = { State.ACTIVE, State.ERRORED, State.UNINITIALIZED }, desiredState = State.STOPPED )
-    private ListenableFuture<Void> doStop()
+    private CompletableFuture<Void> doStop()
     {
-        final ListenableFuture<Void> future = Futures.immediateFuture(null);
+        final CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
         final RedirectingVirtualHostImpl virtualHost = _virtualHost;
         if (virtualHost != null)
         {
-            return doAfter(virtualHost.closeAsync(), () ->
+            return virtualHost.closeAsync().thenApply(x ->
             {
                 _virtualHost = null;
                 setState(State.STOPPED);
-                return future;
+                return future.join();
             });
         }
         else
@@ -140,28 +135,28 @@ public class RedirectingVirtualHostNodeImpl
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
-        final ListenableFuture<Void> superFuture = super.beforeClose();
+        final CompletableFuture<Void> superFuture = super.beforeClose();
         return closeVirtualHost(superFuture);
     }
 
     @Override
-    protected ListenableFuture<Void> beforeDelete()
+    protected CompletableFuture<Void> beforeDelete()
     {
-        final ListenableFuture<Void> superFuture = super.beforeDelete();
+        final CompletableFuture<Void> superFuture = super.beforeDelete();
         return closeVirtualHost(superFuture);
     }
 
-    private ListenableFuture<Void> closeVirtualHost(final ListenableFuture<Void> superFuture)
+    private CompletableFuture<Void> closeVirtualHost(final CompletableFuture<Void> superFuture)
     {
         final RedirectingVirtualHostImpl virtualHost = _virtualHost;
         if (virtualHost != null)
         {
-            return doAfter(virtualHost.closeAsync(), () -> {
+            return virtualHost.closeAsync().thenApplyAsync(x -> {
                 _virtualHost = null;
-                return superFuture;
-            });
+                return superFuture.join();
+            }, getTaskExecutor());
         }
         else
         {
@@ -253,10 +248,10 @@ public class RedirectingVirtualHostNodeImpl
     }
 
     @Override
-    protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(Class<C> childClass,
-                                                                             Map<String, Object> attributes)
+    protected <C extends ConfiguredObject> CompletableFuture<C> addChildAsync(Class<C> childClass,
+                                                                              Map<String, Object> attributes)
     {
-        if(childClass == VirtualHost.class)
+        if (childClass == VirtualHost.class)
         {
             throw new UnsupportedOperationException("The redirecting virtualhost node automatically manages the creation"
                                                     + " of the redirecting virtualhost. Creating it explicitly is not supported.");
diff --git a/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
index fe0b5b960c..67e210c684 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
@@ -38,10 +38,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -137,16 +136,16 @@ public class ManagementModeStoreHandlerTest extends UnitTestBase
             }
 
             @Override
-            protected ListenableFuture<Void> onClose()
+            protected CompletableFuture<Void> onClose()
             {
-                return Futures.immediateFuture(null);
+                return CompletableFuture.completedFuture(null);
             }
 
             @Override
             @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
-            protected ListenableFuture<Void> startQuiesced()
+            protected CompletableFuture<Void> startQuiesced()
             {
-                return Futures.immediateFuture(null);
+                return CompletableFuture.completedFuture(null);
             }
         };
         _systemConfig.open();
diff --git a/broker-core/src/test/java/org/apache/qpid/server/consumer/TestConsumerTarget.java b/broker-core/src/test/java/org/apache/qpid/server/consumer/TestConsumerTarget.java
index 421ef3962b..d7aa58b808 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/consumer/TestConsumerTarget.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/consumer/TestConsumerTarget.java
@@ -26,9 +26,7 @@ import static org.mockito.Mockito.when;
 
 import java.security.Principal;
 import java.util.ArrayList;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.message.MessageContainer;
 import org.apache.qpid.server.message.MessageInstance;
@@ -185,10 +183,10 @@ public class TestConsumerTarget implements ConsumerTarget<TestConsumerTarget>
     }
 
     @Override
-    public ListenableFuture<Void> consumerRemoved(final MessageInstanceConsumer sub)
+    public CompletableFuture<Void> consumerRemoved(final MessageInstanceConsumer sub)
     {
         close();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     public void setState(State state)
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java b/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java
index 000ab7e985..7f7f56f21b 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java
@@ -48,11 +48,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -643,8 +642,8 @@ public class VirtualHostTest extends UnitTestBase
         final Subject subject =
                 new Subject(true, Set.of(principal), Set.of(), Set.of());
         when(connection.getSubject()).thenReturn(subject);
-        final ListenableFuture<Void> listenableFuture = Futures.immediateFuture(null);
-        when(connection.closeAsync()).thenReturn(listenableFuture);
+        final CompletableFuture<Void> completableFuture = CompletableFuture.completedFuture(null);
+        when(connection.closeAsync()).thenReturn(completableFuture);
         when(connection.getCreatedTime()).thenReturn(new Date());
         return connection;
     }
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
index 18ccbdf08f..05e8183b77 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
@@ -35,11 +35,9 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
 import org.junit.jupiter.api.Test;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
@@ -120,7 +118,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         assertEquals(engine, car.getChildById(TestEngine.class, engine.getId()));
         assertEquals(engine, car.getChildByName(TestEngine.class, engine.getName()));
 
-        final ListenableFuture attainedChild = car.getAttainedChildByName(TestEngine.class, engine.getName());
+        final CompletableFuture attainedChild = car.getAttainedChildByName(TestEngine.class, engine.getName());
         assertNotNull(attainedChild);
         assertTrue(attainedChild.isDone(), "Engine should have already attained state");
     }
@@ -138,7 +136,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         assertEquals(engine, car.getChildById(TestEngine.class, engine.getId()));
         assertEquals(engine, car.getChildByName(TestEngine.class, engine.getName()));
 
-        final ListenableFuture attainedChild = car.getAttainedChildByName(TestEngine.class, engine.getName());
+        final CompletableFuture attainedChild = car.getAttainedChildByName(TestEngine.class, engine.getName());
         assertNotNull(attainedChild);
         assertFalse(attainedChild.isDone(), "Engine should not have yet attained state");
 
@@ -151,7 +149,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
     @Test
     public void testOpenAwaitsChildToAttainState() throws Exception
     {
-        final SettableFuture<Void> engineStateChangeControllingFuture = SettableFuture.create();
+        final CompletableFuture<Void> engineStateChangeControllingFuture = new CompletableFuture<>();
         final TestCar car = recoverParentAndChild();
 
         // Check we can observe the recovered child from the parent
@@ -159,10 +157,10 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         final TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
         engine.setStateChangeFuture(engineStateChangeControllingFuture);
 
-        final ListenableFuture carFuture = car.openAsync();
+        final CompletableFuture carFuture = car.openAsync();
         assertFalse(carFuture.isDone(), "car open future has completed before engine has attained state");
 
-        engineStateChangeControllingFuture.set(null);
+        engineStateChangeControllingFuture.complete(null);
 
         assertTrue(carFuture.isDone(), "car open future has not completed");
         carFuture.get();
@@ -171,7 +169,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
     @Test
     public void testOpenAwaitsChildToAttainState_ChildStateChangeAsyncErrors() throws Exception
     {
-        final SettableFuture<Void> engineStateChangeControllingFuture = SettableFuture.create();
+        final CompletableFuture<Void> engineStateChangeControllingFuture = new CompletableFuture<>();
 
         final TestCar car = recoverParentAndChild();
 
@@ -180,10 +178,10 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         final TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
         engine.setStateChangeFuture(engineStateChangeControllingFuture);
 
-        final ListenableFuture carFuture = car.openAsync();
+        final CompletableFuture carFuture = car.openAsync();
         assertFalse(carFuture.isDone(), "car open future has completed before engine has attained state");
 
-        engineStateChangeControllingFuture.setException(new RuntimeException("child attain state exception"));
+        engineStateChangeControllingFuture.completeExceptionally(new RuntimeException("child attain state exception"));
 
         assertTrue(carFuture.isDone(), "car open future has not completed");
         carFuture.get();
@@ -202,7 +200,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
 
         engine.setStateChangeException(new RuntimeException("child attain state exception"));
 
-        final ListenableFuture carFuture = car.openAsync();
+        final CompletableFuture carFuture = car.openAsync();
 
         assertTrue(carFuture.isDone(), "car open future has not completed");
         carFuture.get();
@@ -213,14 +211,14 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
     @Test
     public void testCreateAwaitsAttainState()
     {
-        final SettableFuture<Void> stateChangeFuture = SettableFuture.create();
+        final CompletableFuture<Void> stateChangeFuture = new CompletableFuture<>();
         final TestCar car = _model.getObjectFactory().create(TestCar.class, Map.of(ConfiguredObject.NAME, "myCar"), null);
         final Map<String, Object> engineAttributes = Map.of(ConfiguredObject.NAME, "myEngine",
                 TestEngine.STATE_CHANGE_FUTURE, stateChangeFuture);
-        final ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+        final CompletableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
         assertFalse(engine.isDone(), "create child has completed before state change completes");
 
-        stateChangeFuture.set(null);
+        stateChangeFuture.complete(null);
 
         assertTrue(engine.isDone(), "create child has not completed");
     }
@@ -228,15 +226,15 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
     @Test
     public void testCreateAwaitsAttainState_StateChangeAsyncErrors()
     {
-        final SettableFuture stateChangeFuture = SettableFuture.create();
+        final CompletableFuture stateChangeFuture = new CompletableFuture<>();
         final RuntimeException stateChangeException = new RuntimeException("state change error");
         final TestCar car = _model.getObjectFactory().create(TestCar.class, Map.of(ConfiguredObject.NAME, "myCar"), null);
         final Map<String, Object> engineAttributes = Map.of(ConfiguredObject.NAME, "myEngine",
                 TestEngine.STATE_CHANGE_FUTURE, stateChangeFuture);
-        final ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+        final CompletableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
         assertFalse(engine.isDone(), "create child has completed before state change completes");
 
-        stateChangeFuture.setException(stateChangeException);
+        stateChangeFuture.completeExceptionally(stateChangeException);
 
         assertTrue(engine.isDone(), "create child has not completed");
         final ExecutionException ee = assertThrows(ExecutionException.class, engine::get, "Exception not thrown");
@@ -252,7 +250,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         final TestCar car = _model.getObjectFactory().create(TestCar.class, Map.of(ConfiguredObject.NAME, "myCar"), null);
         final Map<String, Object> engineAttributes = Map.of(ConfiguredObject.NAME, "myEngine",
                 TestEngine.STATE_CHANGE_EXCEPTION, stateChangeException);
-        final ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+        final CompletableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
         assertTrue(engine.isDone(), "create child has not completed");
         final ExecutionException ee = assertThrows(ExecutionException.class, engine::get, "Exception not thrown");
         assertSame(stateChangeException, ee.getCause());
@@ -263,21 +261,21 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
     @Test
     public void testCloseAwaitsChildCloseCompletion()
     {
-        final SettableFuture<Void> engineCloseControllingFuture = SettableFuture.create();
+        final CompletableFuture<Void> engineCloseControllingFuture = new CompletableFuture<>();
         final TestCar car = _model.getObjectFactory().create(TestCar.class, Map.of(ConfiguredObject.NAME, "myCar"), null);
         final String engineName = "myEngine";
         final Map<String, Object> engineAttributes = Map.of(ConfiguredObject.NAME, engineName,
                 TestEngine.BEFORE_CLOSE_FUTURE, engineCloseControllingFuture);
         final TestEngine engine = (TestEngine) car.createChild(TestEngine.class, engineAttributes);
-        final ListenableFuture carListenableFuture = car.closeAsync();
-        assertFalse(carListenableFuture.isDone(), "car close future has completed before engine closed");
+        final CompletableFuture carCompletableFuture = car.closeAsync();
+        assertFalse(carCompletableFuture.isDone(), "car close future has completed before engine closed");
         assertSame(engine, car.getChildById(TestEngine.class, engine.getId()),
                    "engine deregistered from car too early");
 
 
-        engineCloseControllingFuture.set(null);
+        engineCloseControllingFuture.complete(null);
 
-        assertTrue(carListenableFuture.isDone(), "car close future has not completed");
+        assertTrue(carCompletableFuture.isDone(), "car close future has not completed");
         assertNull(car.getChildById(TestEngine.class, engine.getId()), "engine not deregistered");
     }
 
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java
index d8286a5eca..b499db4ae3 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java
@@ -22,9 +22,7 @@
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -36,10 +34,10 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
 {
     public static final int TEST_TEMPERATURE = 50;
     @ManagedAttributeField
-    private ListenableFuture<Void> _beforeCloseFuture = Futures.immediateFuture(null);
+    private CompletableFuture<Void> _beforeCloseFuture = CompletableFuture.completedFuture(null);
 
     @ManagedAttributeField
-    private Object _stateChangeFuture = Futures.immediateFuture(null);
+    private Object _stateChangeFuture = CompletableFuture.completedFuture(null);
 
     @ManagedAttributeField
     private RuntimeException _stateChangeException;
@@ -57,9 +55,9 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
     }
 
     @Override
-    public void setBeforeCloseFuture(final ListenableFuture<Void> listenableFuture)
+    public void setBeforeCloseFuture(final CompletableFuture<Void> completableFuture)
     {
-        _beforeCloseFuture = listenableFuture;
+        _beforeCloseFuture = completableFuture;
     }
 
     @Override
@@ -69,9 +67,9 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
     }
 
     @Override
-    public void setStateChangeFuture(final ListenableFuture<Void> listenableFuture)
+    public void setStateChangeFuture(final CompletableFuture<Void> completableFuture)
     {
-        _stateChangeFuture = listenableFuture;
+        _stateChangeFuture = completableFuture;
     }
 
     @Override
@@ -87,7 +85,7 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
     }
 
     @Override
-    protected ListenableFuture<Void> beforeClose()
+    protected CompletableFuture<Void> beforeClose()
     {
         return _beforeCloseFuture;
     }
@@ -100,7 +98,7 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings({"unchecked", "unused"})
-    private ListenableFuture<Void> onActivate()
+    private CompletableFuture<Void> onActivate()
     {
         final RuntimeException stateChangeException = _stateChangeException;
         if (stateChangeException != null)
@@ -108,7 +106,7 @@ public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends
             throw stateChangeException;
         }
         setState(State.ACTIVE);
-        return (ListenableFuture<Void>) _stateChangeFuture;
+        return (CompletableFuture<Void>) _stateChangeFuture;
     }
 
     @Override
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractGaugeImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractGaugeImpl.java
index 51416ecda3..4c9bf22e3e 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractGaugeImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractGaugeImpl.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.State;
@@ -47,9 +45,9 @@ public abstract class TestAbstractGaugeImpl<X extends TestAbstractGaugeImpl<X>>
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings({"unused"})
-    private ListenableFuture<Void> onActivate()
+    private CompletableFuture<Void> onActivate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 }
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
index 7c81f8cf29..1b0bd12b96 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
@@ -21,9 +21,7 @@
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
 import java.util.Map;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.State;
@@ -47,9 +45,9 @@ public class TestAbstractInstrumentPanelImpl<X extends TestAbstractInstrumentPan
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings({"unused"})
-    private ListenableFuture<Void> onActivate()
+    private CompletableFuture<Void> onActivate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 }
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
index 741ba0f72b..773c59f259 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
@@ -21,11 +21,9 @@
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.StateTransition;
@@ -50,10 +48,10 @@ public class TestAbstractSensorImpl<X extends TestAbstractSensorImpl<X>> extends
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings({"unused"})
-    private ListenableFuture<Void> onActivate()
+    private CompletableFuture<Void> onActivate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java
index 47bebbbf87..ab36f54fc7 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java
@@ -20,7 +20,7 @@
  */
 package org.apache.qpid.server.model.testmodels.hierarchy;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ManagedAttribute;
@@ -42,7 +42,7 @@ public interface TestEngine<X extends TestEngine<X>> extends ConfiguredObject<X>
     Object getBeforeCloseFuture();
 
     @SuppressWarnings("unused")
-    void setBeforeCloseFuture(ListenableFuture<Void> listenableFuture);
+    void setBeforeCloseFuture(CompletableFuture<Void> completableFuture);
 
     /* Injectable state change future, used to control when/how asynch state transition completes during the test */
 
@@ -50,7 +50,7 @@ public interface TestEngine<X extends TestEngine<X>> extends ConfiguredObject<X>
     @SuppressWarnings("unused")
     Object getStateChangeFuture();
 
-    void setStateChangeFuture(ListenableFuture<Void> listenableFuture);
+    void setStateChangeFuture(CompletableFuture<Void> completableFuture);
 
     /* Injectable exception, used to introduce an exception into a state change transition */
 
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java
index dca112e203..edf95b9064 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java
@@ -28,11 +28,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.junit.jupiter.api.Test;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
@@ -271,7 +270,7 @@ public class AbstractConfiguredObjectTest extends UnitTestBase
         final TestConfiguredObject parent = new TestConfiguredObject("parent")
         {
             @Override
-            protected ListenableFuture<Void> doDelete()
+            protected CompletableFuture<Void> doDelete()
             {
                 throw expectedException;
             }
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java
index 2761554ba5..f59cc13c89 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java
@@ -23,9 +23,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
@@ -127,25 +125,25 @@ public class TestConfiguredObject extends AbstractConfiguredObject
 
     @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.ACTIVE )
     @SuppressWarnings("unused")
-    protected ListenableFuture<Void> activate()
+    protected CompletableFuture<Void> activate()
     {
         if (_throwExceptionOnActivate)
         {
             setState(State.ERRORED);
-            return Futures.immediateFailedFuture(new IllegalConfigurationException("failed to activate"));
+            return CompletableFuture.failedFuture(new IllegalConfigurationException("failed to activate"));
         }
         else
         {
             setState(State.ACTIVE);
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
     }
 
     @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED, State.ACTIVE}, desiredState = State.DELETED )
-    protected ListenableFuture<Void> doDelete()
+    protected CompletableFuture<Void> doDelete()
     {
         setState(State.DELETED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
     
     public boolean isOpened()
diff --git a/broker-core/src/test/java/org/apache/qpid/server/security/encryption/AESGCMKeyFileEncrypterTest.java b/broker-core/src/test/java/org/apache/qpid/server/security/encryption/AESGCMKeyFileEncrypterTest.java
index 518fc43d50..4666d3c11a 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/security/encryption/AESGCMKeyFileEncrypterTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/security/encryption/AESGCMKeyFileEncrypterTest.java
@@ -40,6 +40,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 import javax.crypto.SecretKeyFactory;
@@ -48,7 +49,6 @@ import javax.crypto.spec.SecretKeySpec;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.util.concurrent.SettableFuture;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -280,13 +280,13 @@ public class AESGCMKeyFileEncrypterTest extends UnitTestBase
                 SystemConfig.TYPE, JsonSystemConfigImpl.SYSTEM_CONFIG_TYPE,
                 SystemConfig.STARTUP_LOGGED_TO_SYSTEM_OUT, Boolean.FALSE,
                 SystemConfig.CONTEXT, context);
-        final SettableFuture<SystemConfig<?>> configFuture = SettableFuture.create();
+        final CompletableFuture<SystemConfig<?>> configFuture = new CompletableFuture<>();
         _systemLauncher = new SystemLauncher(new SystemLauncherListener.DefaultSystemLauncherListener()
         {
             @Override
             public void onContainerResolve(final SystemConfig<?> systemConfig)
             {
-                configFuture.set(systemConfig);
+                configFuture.complete(systemConfig);
             }
         });
         _systemLauncher.startup(attributes);
diff --git a/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecovererTest.java b/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecovererTest.java
index 3c9dcf11bb..a9274daa55 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecovererTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AsynchronousMessageStoreRecovererTest.java
@@ -38,9 +38,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -89,7 +89,7 @@ public class AsynchronousMessageStoreRecovererTest extends UnitTestBase
         when(_virtualHost.getChildren(eq(Queue.class))).thenReturn(Set.of(queue));
 
         final AsynchronousMessageStoreRecoverer recoverer = new AsynchronousMessageStoreRecoverer();
-        final ListenableFuture<Void> result = recoverer.recover(_virtualHost);
+        final CompletableFuture<Void> result = recoverer.recover(_virtualHost);
         final ExecutionException thrown = assertThrows(ExecutionException.class,
                 result::get,
                 "ServerScopedRuntimeException should be rethrown");
@@ -103,7 +103,7 @@ public class AsynchronousMessageStoreRecovererTest extends UnitTestBase
         when(_virtualHost.getChildren(eq(Queue.class))).thenReturn(Set.of(queue));
 
         final AsynchronousMessageStoreRecoverer recoverer = new AsynchronousMessageStoreRecoverer();
-        final ListenableFuture<Void> result = recoverer.recover(_virtualHost);
+        final CompletableFuture<Void> result = recoverer.recover(_virtualHost);
         assertNull(result.get());
     }
 
@@ -134,7 +134,7 @@ public class AsynchronousMessageStoreRecovererTest extends UnitTestBase
         when(_store.newMessageStoreReader()).thenReturn(storeReader);
 
         final AsynchronousMessageStoreRecoverer recoverer = new AsynchronousMessageStoreRecoverer();
-        final ListenableFuture<Void> result = recoverer.recover(_virtualHost);
+        final CompletableFuture<Void> result = recoverer.recover(_virtualHost);
         assertNull(result.get());
 
         verify(orphanedMessage, times(1)).remove();
diff --git a/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java b/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
index 85e049bb00..50fb04bd05 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
@@ -40,11 +40,9 @@ import java.security.AccessControlException;
 import java.util.Collection;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -556,9 +554,9 @@ public class AbstractStandardVirtualHostNodeTest extends UnitTestBase
         }
 
         @Override
-        protected ListenableFuture<Void> activate()
+        protected CompletableFuture<Void> activate()
         {
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
 
         @Override
diff --git a/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractLegacyAccessControlProvider.java b/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractLegacyAccessControlProvider.java
index 3de7b1cb2c..bc1a2ac6b8 100644
--- a/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractLegacyAccessControlProvider.java
+++ b/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractLegacyAccessControlProvider.java
@@ -21,9 +21,8 @@
 package org.apache.qpid.server.security.access.plugins;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,7 +85,7 @@ abstract class AbstractLegacyAccessControlProvider<X extends AbstractLegacyAcces
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
 
         final boolean isManagementMode = getModel().getAncestor(SystemConfig.class, this).isManagementMode();
@@ -107,7 +106,7 @@ abstract class AbstractLegacyAccessControlProvider<X extends AbstractLegacyAcces
                 throw e;
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 
diff --git a/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AclFileAccessControlProviderImpl.java b/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AclFileAccessControlProviderImpl.java
index 5cb8a441d9..4537d71704 100644
--- a/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AclFileAccessControlProviderImpl.java
+++ b/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AclFileAccessControlProviderImpl.java
@@ -21,11 +21,10 @@
 package org.apache.qpid.server.security.access.plugins;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.logging.messages.AccessControlMessages;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,7 +96,7 @@ public class AclFileAccessControlProviderImpl
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> activate()
+    private CompletableFuture<Void> activate()
     {
 
         try
@@ -117,7 +116,7 @@ public class AclFileAccessControlProviderImpl
                 throw e;
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-plugins/amqp-0-10-protocol/src/test/java/org/apache/qpid/server/protocol/v0_10/ServerSessionTest.java b/broker-plugins/amqp-0-10-protocol/src/test/java/org/apache/qpid/server/protocol/v0_10/ServerSessionTest.java
index 9d0b12febe..ef1d9fc878 100644
--- a/broker-plugins/amqp-0-10-protocol/src/test/java/org/apache/qpid/server/protocol/v0_10/ServerSessionTest.java
+++ b/broker-plugins/amqp-0-10-protocol/src/test/java/org/apache/qpid/server/protocol/v0_10/ServerSessionTest.java
@@ -29,11 +29,10 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -105,7 +104,7 @@ class ServerSessionTest extends UnitTestBase
         final AMQPConnection_0_10 modelConnection = mock(AMQPConnection_0_10.class);
         when(modelConnection.getCategoryClass()).thenReturn(Connection.class);
         when(modelConnection.getTypeClass()).thenReturn(AMQPConnection_0_10.class);
-        when(modelConnection.closeAsync()).thenReturn(Futures.immediateFuture(null));
+        when(modelConnection.closeAsync()).thenReturn(CompletableFuture.completedFuture(null));
         when(modelConnection.getAddressSpace()).thenReturn(_virtualHost);
         when(modelConnection.getContextProvider()).thenReturn(_virtualHost);
         when(modelConnection.getBroker()).thenReturn(broker);
diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0Impl.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0Impl.java
index d309048cd7..1f3d7c6349 100644
--- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0Impl.java
+++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0Impl.java
@@ -20,7 +20,6 @@
  */
 package org.apache.qpid.server.protocol.v1_0;
 
-import static com.google.common.util.concurrent.Futures.allAsList;
 import static org.apache.qpid.server.protocol.v1_0.type.extensions.soleconn.SoleConnectionConnectionProperties.SOLE_CONNECTION_ENFORCEMENT_POLICY;
 
 import java.net.SocketAddress;
@@ -43,6 +42,7 @@ import java.util.Optional;
 import java.util.Queue;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentSkipListMap;
@@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicReference;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.PeekingIterator;
 import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.EventLogger;
 import org.apache.qpid.server.logging.messages.ResourceLimitMessages;
@@ -994,7 +993,7 @@ public class AMQPConnection_1_0Impl extends AbstractAMQPConnection<AMQPConnectio
             error.setInfo(Map.of(Symbol.valueOf("sole-connection-enforcement"), true));
 
             final EventLogger logger = getEventLogger();
-            final List<ListenableFuture<Void>> rescheduleFutures = new ArrayList<>();
+            final List<CompletableFuture<Void>> rescheduleFutures = new ArrayList<>();
             for (final AMQPConnection_1_0<?> connection : e.getExistingConnections())
             {
                 if (!connection.isClosing())
@@ -1006,7 +1005,8 @@ public class AMQPConnection_1_0Impl extends AbstractAMQPConnection<AMQPConnectio
                             String.format("Closing existing connection '%s'", connection.getName()), e.getMessage()));
                 }
             }
-            doAfter(allAsList(rescheduleFutures), () -> doOnIOThreadAsync(() -> receiveOpenInternal(addressSpace)));
+            CompletableFuture.allOf(rescheduleFutures.toArray(CompletableFuture[]::new))
+                    .thenRunAsync(() -> doOnIOThreadAsync(() -> receiveOpenInternal(addressSpace)), getTaskExecutor());
         }
     }
 
diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkImpl.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkImpl.java
index e2a45d32db..a268d7df22 100644
--- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkImpl.java
+++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkImpl.java
@@ -23,18 +23,13 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Objects;
 import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.SettableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.protocol.LinkModel;
 import org.apache.qpid.server.protocol.v1_0.type.AmqpErrorException;
@@ -86,7 +81,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
     }
 
     @Override
-    public final synchronized ListenableFuture<? extends LinkEndpoint<S, T>> attach(final Session_1_0 session, final Attach attach)
+    public final synchronized CompletableFuture<? extends LinkEndpoint<S, T>> attach(final Session_1_0 session, final Attach attach)
     {
         try
         {
@@ -108,7 +103,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
                             : (ConfiguredObject<?>) session.getReceivingDestination(this, (Target) getTarget()).getMessageDestination();
                     targetObject.authorise(operation);
                 }
-                final SettableFuture<LinkEndpoint<S, T>> future = SettableFuture.create();
+                final CompletableFuture<LinkEndpoint<S, T>> future = new CompletableFuture<>();
                 _thiefQueue.add(new ThiefInformation(session, attach, future));
                 startLinkStealingIfNecessary();
                 return future;
@@ -122,7 +117,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
 
                 _linkEndpoint.receiveAttach(attach);
                 _linkRegistry.linkChanged(this);
-                return Futures.immediateFuture(_linkEndpoint);
+                return CompletableFuture.completedFuture(_linkEndpoint);
             }
         }
         catch (Exception e)
@@ -227,7 +222,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
         return linkEndpoint;
     }
 
-    private ListenableFuture<? extends LinkEndpoint<S, T>> rejectLink(final Session_1_0 session, Throwable t)
+    private CompletableFuture<? extends LinkEndpoint<S, T>> rejectLink(final Session_1_0 session, Throwable t)
     {
         if (t instanceof AmqpErrorException)
         {
@@ -238,7 +233,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
             _linkEndpoint =
                     new ErrantLinkEndpoint<>(this, session, new Error(AmqpError.INTERNAL_ERROR, t.getMessage()));
         }
-        return Futures.immediateFuture(_linkEndpoint);
+        return CompletableFuture.completedFuture(_linkEndpoint);
     }
 
     private void startLinkStealingIfNecessary()
@@ -255,24 +250,20 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
         ThiefInformation thiefInformation;
         if ((thiefInformation = _thiefQueue.poll()) != null)
         {
-            AbstractConfiguredObject.addFutureCallback(doStealLink(thiefInformation.getSession(),
-                                                                   thiefInformation.getAttach()),
-                                                       new FutureCallback<>()
-                                                       {
-                                                           @Override
-                                                           public void onSuccess(final LinkEndpoint<S, T> result)
-                                                           {
-                                                               thiefInformation.getFuture().set(result);
-                                                               stealLink();
-                                                           }
-
-                                                           @Override
-                                                           public void onFailure(final Throwable t)
-                                                           {
-                                                               thiefInformation.getFuture().setException(t);
-                                                               stealLink();
-                                                           }
-                                                       }, MoreExecutors.directExecutor());
+            doStealLink(thiefInformation.getSession(), thiefInformation.getAttach())
+                    .whenComplete((result, error) ->
+                    {
+                        if (error != null)
+                        {
+                            thiefInformation.getFuture().completeExceptionally(error);
+                            stealLink();
+                        }
+                        else
+                        {
+                            thiefInformation.getFuture().complete(result);
+                            stealLink();
+                        }
+                    });
         }
         else
         {
@@ -280,9 +271,9 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
         }
     }
 
-    private ListenableFuture<LinkEndpoint<S, T>> doStealLink(final Session_1_0 session, final Attach attach)
+    private CompletableFuture<LinkEndpoint<S, T>> doStealLink(final Session_1_0 session, final Attach attach)
     {
-        final SettableFuture<LinkEndpoint<S, T>> returnFuture = SettableFuture.create();
+        final CompletableFuture<LinkEndpoint<S, T>> returnFuture = new CompletableFuture<>();
         final LinkEndpoint<S, T> linkEndpoint = _linkEndpoint;
 
         // check whether linkEndpoint has been closed in the mean time
@@ -312,20 +303,20 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
 
     private void doLinkStealAndHandleExceptions(final Session_1_0 session,
                                                 final Attach attach,
-                                                final SettableFuture<LinkEndpoint<S, T>> returnFuture)
+                                                final CompletableFuture<LinkEndpoint<S, T>> returnFuture)
     {
         try
         {
-            returnFuture.set(attach(session, attach).get());
+            returnFuture.complete(attach(session, attach).get());
         }
         catch (InterruptedException e)
         {
-            returnFuture.setException(e);
+            returnFuture.completeExceptionally(e);
             Thread.currentThread().interrupt();
         }
         catch (ExecutionException e)
         {
-            returnFuture.setException(e.getCause());
+            returnFuture.completeExceptionally(e.getCause());
         }
     }
 
@@ -346,11 +337,11 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
     {
         private final Session_1_0 _session;
         private final Attach _attach;
-        private final SettableFuture<LinkEndpoint<S, T>> _future;
+        private final CompletableFuture<LinkEndpoint<S, T>> _future;
 
         ThiefInformation(final Session_1_0 session,
                          final Attach attach,
-                         final SettableFuture<LinkEndpoint<S, T>> future)
+                         final CompletableFuture<LinkEndpoint<S, T>> future)
         {
             _session = session;
             _attach = attach;
@@ -367,7 +358,7 @@ public class LinkImpl<S extends BaseSource, T extends BaseTarget> implements Lin
             return _attach;
         }
 
-        SettableFuture<LinkEndpoint<S, T>> getFuture()
+        CompletableFuture<LinkEndpoint<S, T>> getFuture()
         {
             return _future;
         }
diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java
index 681194befe..fce760593d 100644
--- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java
+++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java
@@ -20,7 +20,7 @@
  */
 package org.apache.qpid.server.protocol.v1_0;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.protocol.v1_0.type.BaseSource;
 import org.apache.qpid.server.protocol.v1_0.type.BaseTarget;
@@ -29,7 +29,7 @@ import org.apache.qpid.server.protocol.v1_0.type.transport.Attach;
 
 public interface Link_1_0<S extends BaseSource, T extends BaseTarget> extends LinkDefinition<S, T>
 {
-    ListenableFuture<? extends LinkEndpoint<S, T>> attach(Session_1_0 session, final Attach attach);
+    CompletableFuture<? extends LinkEndpoint<S, T>> attach(Session_1_0 session, final Attach attach);
 
     void linkClosed();
 
diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
index 2249257fdf..a3ee227446 100644
--- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
+++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
@@ -37,6 +37,7 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
@@ -44,9 +45,6 @@ import java.util.stream.Collectors;
 import javax.security.auth.Subject;
 
 import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -203,9 +201,61 @@ public class Session_1_0 extends AbstractAMQPSession<Session_1_0, ConsumerTarget
                     link = getAddressSpace().getReceivingLink(getConnection().getRemoteContainerId(), attach.getName());
                 }
 
-                final ListenableFuture<? extends LinkEndpoint<?,?>> future = link.attach(this, attach);
+                final CompletableFuture<? extends LinkEndpoint<?,?>> future = link.attach(this, attach);
 
-                addFutureCallback(future, new EndpointCreationCallback(attach), MoreExecutors.directExecutor());
+                future.whenComplete((endpoint, error) ->
+                {
+                    if (error != null)
+                    {
+                        String errorMessage = String.format("Failed to create LinkEndpoint in response to Attach: %s", attach);
+                        LOGGER.error(errorMessage, error);
+                        throw new ConnectionScopedRuntimeException(errorMessage, error);
+                    }
+                    else
+                    {
+                        doOnIOThreadAsync(() ->
+                        {
+                            _associatedLinkEndpoints.add(endpoint);
+                            _inputHandleToEndpoint.put(attach.getHandle(), endpoint);
+                            UnsignedInteger nextAvailableOutputHandle = findNextAvailableOutputHandle();
+                            if (nextAvailableOutputHandle == null)
+                            {
+                                endpoint.close(new Error(AmqpError.RESOURCE_LIMIT_EXCEEDED,
+                                                         String.format(
+                                                                 "Cannot find free handle for endpoint '%s' on session '%s'",
+                                                                 attach.getName(),
+                                                                 endpoint.getSession().toLogString())));
+                            }
+                            else
+                            {
+                                endpoint.setLocalHandle(nextAvailableOutputHandle);
+                                if (endpoint instanceof ErrantLinkEndpoint)
+                                {
+                                    endpoint.sendAttach();
+                                    ((ErrantLinkEndpoint) endpoint).closeWithError();
+                                }
+                                else
+                                {
+
+                                    if (!_endpointToOutputHandle.containsKey(endpoint))
+                                    {
+                                        _endpointToOutputHandle.put(endpoint, endpoint.getLocalHandle());
+                                        checkMessageDestinationFlowForReceivingLinkEndpoint(endpoint);
+                                        endpoint.sendAttach();
+                                        endpoint.start();
+                                    }
+                                    else
+                                    {
+                                        final End end = new End();
+                                        end.setError(new Error(AmqpError.INTERNAL_ERROR,
+                                                               "Endpoint is already registered with session."));
+                                        endpoint.getSession().end(end);
+                                    }
+                                }
+                            }
+                        });
+                    }
+                });
             }
         }
     }
@@ -1360,69 +1410,4 @@ public class Session_1_0 extends AbstractAMQPSession<Session_1_0, ConsumerTarget
             }
         }
     }
-
-    private class EndpointCreationCallback<T extends LinkEndpoint<? extends BaseSource, ? extends BaseTarget>> implements FutureCallback<T>
-    {
-
-        private final Attach _attach;
-
-        EndpointCreationCallback(final Attach attach)
-        {
-            _attach = attach;
-        }
-
-        @Override
-        public void onSuccess(final T endpoint)
-        {
-            doOnIOThreadAsync(() ->
-            {
-                _associatedLinkEndpoints.add(endpoint);
-                _inputHandleToEndpoint.put(_attach.getHandle(), endpoint);
-                UnsignedInteger nextAvailableOutputHandle = findNextAvailableOutputHandle();
-                if (nextAvailableOutputHandle == null)
-                {
-                    endpoint.close(new Error(AmqpError.RESOURCE_LIMIT_EXCEEDED,
-                                             String.format(
-                                                     "Cannot find free handle for endpoint '%s' on session '%s'",
-                                                     _attach.getName(),
-                                                     endpoint.getSession().toLogString())));
-                }
-                else
-                {
-                    endpoint.setLocalHandle(nextAvailableOutputHandle);
-                    if (endpoint instanceof ErrantLinkEndpoint)
-                    {
-                        endpoint.sendAttach();
-                        ((ErrantLinkEndpoint) endpoint).closeWithError();
-                    }
-                    else
-                    {
-
-                        if (!_endpointToOutputHandle.containsKey(endpoint))
-                        {
-                            _endpointToOutputHandle.put(endpoint, endpoint.getLocalHandle());
-                            checkMessageDestinationFlowForReceivingLinkEndpoint(endpoint);
-                            endpoint.sendAttach();
-                            endpoint.start();
-                        }
-                        else
-                        {
-                            final End end = new End();
-                            end.setError(new Error(AmqpError.INTERNAL_ERROR,
-                                                   "Endpoint is already registered with session."));
-                            endpoint.getSession().end(end);
-                        }
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onFailure(final Throwable t)
-        {
-            String errorMessage = String.format("Failed to create LinkEndpoint in response to Attach: %s", _attach);
-            LOGGER.error(errorMessage, t);
-            throw new ConnectionScopedRuntimeException(errorMessage, t);
-        }
-    }
 }
diff --git a/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/LinkImplTest.java b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/LinkImplTest.java
index 8312c91870..5e8093a74e 100644
--- a/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/LinkImplTest.java
+++ b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/LinkImplTest.java
@@ -27,7 +27,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -78,7 +78,7 @@ class LinkImplTest
 
         final LinkImpl<Source, Target> link = new LinkImpl<>(REMOTE_CONTAINER_ID, LINK_NAME, Role.RECEIVER, _linkRegistry);
 
-        final ListenableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
+        final CompletableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
         final LinkEndpoint<?, ?> linkEndpoint = future.get();
         assertTrue(linkEndpoint instanceof StandardReceivingLinkEndpoint);
 
@@ -98,7 +98,7 @@ class LinkImplTest
 
         final LinkImpl<Source, Target> link = new LinkImpl<>(REMOTE_CONTAINER_ID, LINK_NAME, Role.SENDER, _linkRegistry);
 
-        final ListenableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
+        final CompletableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
         final LinkEndpoint<?, ?> linkEndpoint = future.get();
         assertTrue(linkEndpoint instanceof SendingLinkEndpoint);
 
@@ -119,7 +119,7 @@ class LinkImplTest
 
         final LinkImpl<Source, Target> link = new LinkImpl<>(REMOTE_CONTAINER_ID, LINK_NAME, Role.RECEIVER, _linkRegistry);
 
-        final ListenableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
+        final CompletableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
         final LinkEndpoint<?, ?> linkEndpoint = future.get();
         assertTrue(linkEndpoint instanceof StandardReceivingLinkEndpoint);
 
@@ -140,7 +140,7 @@ class LinkImplTest
 
         final LinkImpl<Source, Target> link = new LinkImpl<>(REMOTE_CONTAINER_ID, LINK_NAME, Role.SENDER, _linkRegistry);
 
-        final ListenableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
+        final CompletableFuture<? extends LinkEndpoint<?, ?>> future = link.attach(session1, attach1);
         final LinkEndpoint<?, ?> linkEndpoint = future.get();
         assertTrue(linkEndpoint instanceof SendingLinkEndpoint);
 
diff --git a/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/Session_1_0Test.java b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/Session_1_0Test.java
index 1bc14cdd6e..de7fa0e8c2 100644
--- a/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/Session_1_0Test.java
+++ b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/Session_1_0Test.java
@@ -38,11 +38,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -824,10 +823,10 @@ class Session_1_0Test extends UnitTestBase
         when(connection.getDescribedTypeRegistry()).thenReturn(DESCRIBED_TYPE_REGISTRY);
         when(connection.getMaxFrameSize()).thenReturn(512);
         final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
-        when(connection.doOnIOThreadAsync(runnableCaptor.capture())).thenAnswer((Answer<ListenableFuture<Void>>) invocation ->
+        when(connection.doOnIOThreadAsync(runnableCaptor.capture())).thenAnswer((Answer<CompletableFuture<Void>>) invocation ->
         {
             runnableCaptor.getValue().run();
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         });
         final AggregateTicker mockTicker = mock(AggregateTicker.class);
         when(connection.getAggregateTicker()).thenReturn(mockTicker);
diff --git a/broker-plugins/connection-limits/src/main/java/org/apache/qpid/server/user/connection/limits/plugins/AbstractConnectionLimitProvider.java b/broker-plugins/connection-limits/src/main/java/org/apache/qpid/server/user/connection/limits/plugins/AbstractConnectionLimitProvider.java
index 15a6005c85..9a3d79e878 100644
--- a/broker-plugins/connection-limits/src/main/java/org/apache/qpid/server/user/connection/limits/plugins/AbstractConnectionLimitProvider.java
+++ b/broker-plugins/connection-limits/src/main/java/org/apache/qpid/server/user/connection/limits/plugins/AbstractConnectionLimitProvider.java
@@ -20,10 +20,9 @@ package org.apache.qpid.server.user.connection.limits.plugins;
 
 import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -95,7 +94,7 @@ public abstract class AbstractConnectionLimitProvider<X extends AbstractConnecti
 
     @StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings("unused")
-    ListenableFuture<Void> activate()
+    CompletableFuture<Void> activate()
     {
         final boolean isManagementMode = getModel().getAncestor(SystemConfig.class, this).isManagementMode();
         final RuleSetCreator creator;
@@ -130,26 +129,26 @@ public abstract class AbstractConnectionLimitProvider<X extends AbstractConnecti
                 throw e;
             }
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @StateTransition(currentState = {
             State.UNINITIALIZED, State.QUIESCED, State.ACTIVE, State.STOPPED, State.DELETED, State.UNAVAILABLE},
             desiredState = State.ERRORED)
     @SuppressWarnings("unused")
-    ListenableFuture<Void> error()
+    CompletableFuture<Void> error()
     {
         _creator.set(null);
         setState(State.ERRORED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> startQuiesced()
+    private CompletableFuture<Void> startQuiesced()
     {
         setState(State.QUIESCED);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     protected void forceNewRuleSetCreator()
diff --git a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObject.java b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObject.java
index 31b5b7c6d5..98bbcb7c82 100644
--- a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObject.java
+++ b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObject.java
@@ -20,9 +20,6 @@
 
 package org.apache.qpid.server.logging.logback.validator;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
 import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
 import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.ConfigurationChangeListener;
@@ -48,6 +45,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
 public class TestConfiguredObject implements ConfiguredObject<TestConfiguredObject>
 {
@@ -256,26 +254,26 @@ public class TestConfiguredObject implements ConfiguredObject<TestConfiguredObje
     }
 
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildById(Class<C> childClass, UUID id)
+    public <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildById(Class<C> childClass, UUID id)
     {
-        final SettableFuture<C> returnVal = SettableFuture.create();
-        returnVal.set(null);
+        final CompletableFuture<C> returnVal = new CompletableFuture<>();
+        returnVal.complete(null);
         return returnVal;
     }
 
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildByName(Class<C> childClass, String name)
+    public <C extends ConfiguredObject> CompletableFuture<C> getAttainedChildByName(Class<C> childClass, String name)
     {
-        final SettableFuture<C> returnVal = SettableFuture.create();
-        returnVal.set(null);
+        final CompletableFuture<C> returnVal = new CompletableFuture<>();
+        returnVal.complete(null);
         return returnVal;
     }
 
     @Override
-    public <C extends ConfiguredObject> ListenableFuture<C> createChildAsync(Class<C> childClass, Map<String, Object> attributes)
+    public <C extends ConfiguredObject> CompletableFuture<C> createChildAsync(Class<C> childClass, Map<String, Object> attributes)
     {
-        final SettableFuture<C> returnVal = SettableFuture.create();
-        returnVal.set(null);
+        final CompletableFuture<C> returnVal = new CompletableFuture<>();
+        returnVal.complete(null);
         return returnVal;
     }
 
@@ -287,13 +285,11 @@ public class TestConfiguredObject implements ConfiguredObject<TestConfiguredObje
     }
 
     @Override
-    public ListenableFuture<Void> setAttributesAsync(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException
+    public CompletableFuture<Void> setAttributesAsync(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException
     {
         setAttributes(attributes);
 
-        final SettableFuture<Void> returnVal = SettableFuture.create();
-        returnVal.set(null);
-        return returnVal;
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -362,11 +358,9 @@ public class TestConfiguredObject implements ConfiguredObject<TestConfiguredObje
     }
 
     @Override
-    public ListenableFuture<Void> openAsync()
+    public CompletableFuture<Void> openAsync()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
-        returnVal.set(null);
-        return returnVal;
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -375,19 +369,15 @@ public class TestConfiguredObject implements ConfiguredObject<TestConfiguredObje
     }
 
     @Override
-    public ListenableFuture<Void> closeAsync()
+    public CompletableFuture<Void> closeAsync()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
-        returnVal.set(null);
-        return returnVal;
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    public ListenableFuture<Void> deleteAsync()
+    public CompletableFuture<Void> deleteAsync()
     {
-        final SettableFuture<Void> returnVal = SettableFuture.create();
-        returnVal.set(null);
-        return returnVal;
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectFactory.java b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectFactory.java
index a4a68acb66..72295f37f0 100644
--- a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectFactory.java
+++ b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectFactory.java
@@ -20,9 +20,6 @@
 
 package org.apache.qpid.server.logging.logback.validator;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFactory;
 import org.apache.qpid.server.model.Model;
@@ -34,6 +31,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 public class TestConfiguredObjectFactory implements ConfiguredObjectFactory
 {
@@ -67,11 +65,9 @@ public class TestConfiguredObjectFactory implements ConfiguredObjectFactory
     }
 
     @Override
-    public <X extends ConfiguredObject<X>> ListenableFuture<X> createAsync(Class<X> clazz, Map<String, Object> attributes, ConfiguredObject<?> parent)
+    public <X extends ConfiguredObject<X>> CompletableFuture<X> createAsync(Class<X> clazz, Map<String, Object> attributes, ConfiguredObject<?> parent)
     {
-        final SettableFuture<X> returnVal = SettableFuture.create();
-        returnVal.set(create(clazz, attributes, parent));
-        return returnVal;
+        return CompletableFuture.completedFuture(create(clazz, attributes, parent));
     }
 
     @Override
diff --git a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectTypeFactory.java b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectTypeFactory.java
index 80e6294972..cb10e47922 100644
--- a/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectTypeFactory.java
+++ b/broker-plugins/graylog-logging-logback/src/test/java/org/apache/qpid/server/logging/logback/validator/TestConfiguredObjectTypeFactory.java
@@ -20,9 +20,6 @@
 
 package org.apache.qpid.server.logging.logback.validator;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFactory;
 import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory;
@@ -33,6 +30,7 @@ import org.apache.qpid.server.store.UnresolvedConfiguredObject;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 public class TestConfiguredObjectTypeFactory implements ConfiguredObjectTypeFactory<TestConfiguredObject>
 {
@@ -49,11 +47,9 @@ public class TestConfiguredObjectTypeFactory implements ConfiguredObjectTypeFact
     }
 
     @Override
-    public ListenableFuture<TestConfiguredObject> createAsync(ConfiguredObjectFactory factory, Map<String, Object> attributes, ConfiguredObject<?> parent)
+    public CompletableFuture<TestConfiguredObject> createAsync(ConfiguredObjectFactory factory, Map<String, Object> attributes, ConfiguredObject<?> parent)
     {
-        final SettableFuture<TestConfiguredObject> returnVal = SettableFuture.create();
-        returnVal.set(create(factory, attributes, parent));
-        return returnVal;
+        return CompletableFuture.completedFuture(create(factory, attributes, parent));
     }
 
     @Override
diff --git a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
index 72dcd4f6b6..b0804c54f1 100644
--- a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
+++ b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
@@ -22,12 +22,12 @@ package org.apache.qpid.server.logging.logback.jdbc;
 import java.sql.SQLException;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.status.StatusManager;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.logback.AbstractBrokerLogger;
 import org.apache.qpid.server.logging.logback.BrokerLoggerStatusListener;
@@ -160,14 +160,14 @@ public class JDBCBrokerLoggerImpl extends AbstractBrokerLogger<JDBCBrokerLoggerI
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         onCloseOrDelete();
         return super.onClose();
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         onCloseOrDelete();
         return super.onDelete();
diff --git a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/AbstractJDBCMessageStore.java b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/AbstractJDBCMessageStore.java
index 060f3f3c98..5842401719 100644
--- a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/AbstractJDBCMessageStore.java
+++ b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/AbstractJDBCMessageStore.java
@@ -50,8 +50,6 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 
 import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
@@ -1646,7 +1644,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
             }
         }
 
-        synchronized ListenableFuture<Void> flushToStore()
+        synchronized CompletableFuture<Void> flushToStore()
         {
             if (_messageDataRef != null)
             {
@@ -1665,7 +1663,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
                 }
 
             }
-            return Futures.immediateFuture(null);
+            return CompletableFuture.completedFuture(null);
         }
 
         @Override
diff --git a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractLogger.java b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractLogger.java
index f23f63d722..27931ddace 100644
--- a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractLogger.java
+++ b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractLogger.java
@@ -25,13 +25,12 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.Context;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,14 +101,14 @@ public abstract class AbstractLogger<X extends AbstractLogger<X>> extends Abstra
     protected abstract Collection<? extends LogInclusionRule> getLogInclusionRules();
 
     @StateTransition( currentState = { State.ERRORED, State.UNINITIALIZED, State.STOPPED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> doActivate()
+    private CompletableFuture<Void> doActivate()
     {
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         stopLogging();
         return super.onDelete();
diff --git a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractNameAndLevelLogInclusionRule.java b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractNameAndLevelLogInclusionRule.java
index f10cea794b..a8f8e79723 100644
--- a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractNameAndLevelLogInclusionRule.java
+++ b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractNameAndLevelLogInclusionRule.java
@@ -21,12 +21,11 @@
 package org.apache.qpid.server.logging.logback;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.filter.Filter;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.LogLevel;
 import org.apache.qpid.server.model.AbstractConfiguredObject;
@@ -84,18 +83,18 @@ public abstract class AbstractNameAndLevelLogInclusionRule<X extends AbstractNam
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         QpidLoggerTurboFilter.filterRemovedFromRootContext(_filter);
         return super.onDelete();
     }
 
     @StateTransition( currentState = { State.ERRORED, State.UNINITIALIZED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> doActivate()
+    private CompletableFuture<Void> doActivate()
     {
         setState(State.ACTIVE);
         QpidLoggerTurboFilter.filterAddedToRootContext(_filter);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 }
diff --git a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractPredicateLogInclusionRule.java b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractPredicateLogInclusionRule.java
index da02286136..a18c01f9ee 100644
--- a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractPredicateLogInclusionRule.java
+++ b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/AbstractPredicateLogInclusionRule.java
@@ -21,12 +21,11 @@
 package org.apache.qpid.server.logging.logback;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.filter.Filter;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.LogLevel;
 import org.apache.qpid.server.model.AbstractConfiguredObject;
@@ -87,7 +86,7 @@ public abstract class AbstractPredicateLogInclusionRule<X extends AbstractPredic
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         QpidLoggerTurboFilter.filterRemovedFromRootContext(_filter);
         return super.onDelete();
@@ -95,11 +94,11 @@ public abstract class AbstractPredicateLogInclusionRule<X extends AbstractPredic
 
     @SuppressWarnings("unused")
     @StateTransition( currentState = { State.ERRORED, State.UNINITIALIZED }, desiredState = State.ACTIVE )
-    private ListenableFuture<Void> doActivate()
+    private CompletableFuture<Void> doActivate()
     {
         setState(State.ACTIVE);
         QpidLoggerTurboFilter.filterAddedToRootContext(_filter);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
 }
diff --git a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/BrokerFileLoggerImpl.java b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/BrokerFileLoggerImpl.java
index 482a1c83f2..fe020079bd 100644
--- a/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/BrokerFileLoggerImpl.java
+++ b/broker-plugins/logging-logback/src/main/java/org/apache/qpid/server/logging/logback/BrokerFileLoggerImpl.java
@@ -27,6 +27,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -36,8 +37,6 @@ import ch.qos.logback.core.Context;
 import ch.qos.logback.core.rolling.RollingFileAppender;
 import ch.qos.logback.core.status.StatusListener;
 import ch.qos.logback.core.status.StatusManager;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.logging.LogFileDetails;
 import org.apache.qpid.server.model.Broker;
@@ -208,14 +207,14 @@ public class BrokerFileLoggerImpl extends AbstractBrokerLogger<BrokerFileLoggerI
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         onCloseOrDelete();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onDelete()
+    protected CompletableFuture<Void> onDelete()
     {
         onCloseOrDelete();
         return super.onDelete();
diff --git a/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ProxyMessageSource.java b/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ProxyMessageSource.java
index 5e477d0f6e..2b9f80d465 100644
--- a/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ProxyMessageSource.java
+++ b/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ProxyMessageSource.java
@@ -27,11 +27,11 @@ import java.util.EnumSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -283,7 +283,7 @@ public class ProxyMessageSource implements MessageSource, MessageDestination
         }
 
         @Override
-        public ListenableFuture<Void> consumerRemoved(final MessageInstanceConsumer<WrappingTarget<T>> sub)
+        public CompletableFuture<Void> consumerRemoved(final MessageInstanceConsumer<WrappingTarget<T>> sub)
         {
             return _underlying.consumerRemoved(_consumer);
         }
diff --git a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index 7edbc4079f..4452db7ad2 100644
--- a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -34,10 +34,12 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
+import java.util.function.BiConsumer;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
@@ -50,9 +52,6 @@ import jakarta.servlet.http.HttpServletRequest;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Joiner;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
 import org.eclipse.jetty.io.Connection;
 import org.eclipse.jetty.io.ssl.SslHandshakeListener;
 import org.eclipse.jetty.rewrite.handler.CompactPathRule;
@@ -215,7 +214,7 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
 
     @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
     @SuppressWarnings("unused")
-    private ListenableFuture<Void> doStart()
+    private CompletableFuture<Void> doStart()
     {
         final Collection<HttpPort<?>> httpPorts = getEligibleHttpPorts(getBroker().getPorts());
         if (httpPorts.isEmpty())
@@ -245,11 +244,11 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
             getBroker().getEventLogger().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
         }
         setState(State.ACTIVE);
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
-    protected ListenableFuture<Void> onClose()
+    protected CompletableFuture<Void> onClose()
     {
         getBroker().removeChangeListener(_brokerChangeListener);
         if (_server != null)
@@ -270,7 +269,7 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
             _jettyServerExecutor.shutdown();
         }
         getBroker().getEventLogger().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
@@ -1020,10 +1019,10 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
                         LOGGER.debug("Connector has {} connection(s)", tracker.getConnectionCount());
 
                         final TaskExecutor taskExecutor = getBroker().getTaskExecutor();
-                        tracker.getAllClosedFuture().addListener(new Runnable()
+                        tracker.getAllClosedFuture().whenCompleteAsync(new BiConsumer<Void, Throwable>()
                         {
                             @Override
-                            public void run()
+                            public void accept(final Void unused, final Throwable throwable)
                             {
                                 final int connectionCount = tracker.getConnectionCount();
                                 if (connectionCount == 0)
@@ -1047,8 +1046,7 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
                                 {
                                     LOGGER.debug("Connector still has {} connection(s)", tracker.getConnectionCount());
                                     connector.getConnectedEndPoints().forEach(endPoint -> endPoint.setIdleTimeout(1));
-                                    tracker.getAllClosedFuture()
-                                           .addListener(this, taskExecutor);
+                                    tracker.getAllClosedFuture().whenCompleteAsync(this, taskExecutor);
                                 }
                             }
                         }, taskExecutor);
@@ -1056,32 +1054,31 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
                 }
             }
         }
-
     }
 
     private static class ConnectionTrackingListener implements Connection.Listener
     {
-        private final Map<Connection, SettableFuture<Void>> _closeFutures = new ConcurrentHashMap<>();
+        private final Map<Connection, CompletableFuture<Void>> _closeFutures = new ConcurrentHashMap<>();
 
         @Override
         public void onOpened(final Connection connection)
         {
-            _closeFutures.put(connection, SettableFuture.create());
+            _closeFutures.put(connection, new CompletableFuture<>());
         }
 
         @Override
         public void onClosed(final Connection connection)
         {
-            SettableFuture<Void> closeFuture = _closeFutures.remove(connection);
+            CompletableFuture<Void> closeFuture = _closeFutures.remove(connection);
             if (closeFuture != null)
             {
-                closeFuture.set(null);
+                closeFuture.complete(null);
             }
         }
 
-        public ListenableFuture<List<Void>> getAllClosedFuture()
+        public CompletableFuture<Void> getAllClosedFuture()
         {
-            return Futures.allAsList(_closeFutures.values());
+            return CompletableFuture.allOf(_closeFutures.values().toArray(new CompletableFuture[0]));
         }
 
         public int getConnectionCount()
diff --git a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandler.java b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandler.java
index 6278b5d135..be880945d9 100644
--- a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandler.java
+++ b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandler.java
@@ -31,7 +31,6 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.base.Joiner;
-import com.google.common.util.concurrent.ListenableFuture;
 
 import org.apache.qpid.server.management.plugin.RequestType;
 import org.apache.qpid.server.model.ConfiguredObject;
diff --git a/systests/end-to-end-conversion-tests/src/main/java/org/apache/qpid/systests/end_to_end_conversion/EndToEndConversionTestBase.java b/systests/end-to-end-conversion-tests/src/main/java/org/apache/qpid/systests/end_to_end_conversion/EndToEndConversionTestBase.java
index 61fcef3be3..254c326203 100644
--- a/systests/end-to-end-conversion-tests/src/main/java/org/apache/qpid/systests/end_to_end_conversion/EndToEndConversionTestBase.java
+++ b/systests/end-to-end-conversion-tests/src/main/java/org/apache/qpid/systests/end_to_end_conversion/EndToEndConversionTestBase.java
@@ -32,11 +32,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 
@@ -95,7 +95,7 @@ public class EndToEndConversionTestBase extends BrokerAdminUsingTestBase
         System.out.println("LQDEBUG: " + ClasspathQuery.getCacheStats());
     }
 
-    protected ListenableFuture<ClientResult> runPublisher(final List<ClientInstruction> clientInstructions)
+    protected CompletableFuture<ClientResult> runPublisher(final List<ClientInstruction> clientInstructions)
     {
         List<String> gavs = Arrays.asList(System.getProperty("qpid.systests.end_to_end_conversion.publisherGavs",
                                                              "org.apache.qpid:qpid-jms-client:LATEST")
@@ -104,13 +104,13 @@ public class EndToEndConversionTestBase extends BrokerAdminUsingTestBase
                 "qpid.systests.end_to_end_conversion.publisherAdditionalJavaArguments",
                 "").split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
 
-        return _executorService.submit(() -> {
+        return CompletableFuture.supplyAsync(() -> {
             Thread.currentThread().setName("Publisher");
             return runClient(gavs, additionalJavaArgs, clientInstructions);
-        });
+        }, _executorService);
     }
 
-    protected ListenableFuture<ClientResult> runSubscriber(final List<ClientInstruction> clientInstructions)
+    protected CompletableFuture<ClientResult> runSubscriber(final List<ClientInstruction> clientInstructions)
     {
         List<String> gavs = Arrays.asList(System.getProperty("qpid.systests.end_to_end_conversion.subscriberGavs",
                                                              "org.apache.qpid:qpid-client:LATEST,org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1")
@@ -120,10 +120,10 @@ public class EndToEndConversionTestBase extends BrokerAdminUsingTestBase
                 "qpid.systests.end_to_end_conversion.subscriberAdditionalJavaArguments",
                 "-Dqpid.amqp.version=0-9-1").split(" ")).filter(s -> !s.isEmpty()).collect(Collectors.toList());
 
-        return _executorService.submit(() -> {
+        return CompletableFuture.supplyAsync(() -> {
             Thread.currentThread().setName("Subscriber");
             return runClient(gavs, additionalJavaArgs, clientInstructions);
-        });
+        }, _executorService);
     }
 
     private List<ClientInstruction> amendClientInstructions(List<ClientInstruction> clientInstructions,
diff --git a/systests/end-to-end-conversion-tests/src/test/java/org/apache/qpid/systests/end_to_end_conversion/SimpleConversionTest.java b/systests/end-to-end-conversion-tests/src/test/java/org/apache/qpid/systests/end_to_end_conversion/SimpleConversionTest.java
index 65bcc79603..f7d873a075 100644
--- a/systests/end-to-end-conversion-tests/src/test/java/org/apache/qpid/systests/end_to_end_conversion/SimpleConversionTest.java
+++ b/systests/end-to-end-conversion-tests/src/test/java/org/apache/qpid/systests/end_to_end_conversion/SimpleConversionTest.java
@@ -33,11 +33,12 @@ import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -544,28 +545,33 @@ public class SimpleConversionTest extends EndToEndConversionTestBase
     private List<ClientResult> performTest(final List<ClientInstruction> publisherInstructions,
                                            final List<ClientInstruction> subscriberInstructions) throws Exception
     {
-        final ListenableFuture<ClientResult> publisherFuture = runPublisher(publisherInstructions);
-        final ListenableFuture<ClientResult> subscriberFuture = runSubscriber(subscriberInstructions);
-        try
-        {
-            return Futures.allAsList(publisherFuture, subscriberFuture).get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
-        }
-        catch (ExecutionException e)
-        {
-            final Throwable cause = e.getCause();
-            if (cause instanceof VerificationException)
-            {
-                throw new AssertionError("Client failed verification", cause);
-            }
-            else if (cause instanceof Exception)
-            {
-                throw ((Exception) cause);
-            }
-            else
-            {
-                throw e;
-            }
-        }
+        final CompletableFuture<ClientResult> publisherFuture = runPublisher(publisherInstructions);
+        final CompletableFuture<ClientResult> subscriberFuture = runSubscriber(subscriberInstructions);
+        return Stream.of(publisherFuture, subscriberFuture)
+                .map(future ->
+                {
+                    try
+                    {
+                        return future.get(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
+                    }
+                    catch (ExecutionException | InterruptedException | TimeoutException e)
+                    {
+                        final Throwable cause = e.getCause();
+                        if (cause instanceof VerificationException)
+                        {
+                            throw new AssertionError("Client failed verification", cause);
+                        }
+                        else if (cause instanceof Exception)
+                        {
+                            throw new RuntimeException(cause);
+                        }
+                        else
+                        {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                })
+                .collect(Collectors.toList());
     }
 
     private List<ClientMessage> performProviderAssignedMessageIdTest(final Map<String, String> publisherConnectionUrlConfig) throws Exception
diff --git a/systests/protocol-tests-amqp-1-0/src/main/java/org/apache/qpid/tests/protocol/v1_0/Interaction.java b/systests/protocol-tests-amqp-1-0/src/main/java/org/apache/qpid/tests/protocol/v1_0/Interaction.java
index 99dfb463c1..aa42218b79 100644
--- a/systests/protocol-tests-amqp-1-0/src/main/java/org/apache/qpid/tests/protocol/v1_0/Interaction.java
+++ b/systests/protocol-tests-amqp-1-0/src/main/java/org/apache/qpid/tests/protocol/v1_0/Interaction.java
@@ -31,14 +31,12 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-
 import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
 import org.apache.qpid.server.protocol.v1_0.framing.SASLFrame;
 import org.apache.qpid.server.protocol.v1_0.framing.TransportFrame;
@@ -1186,14 +1184,14 @@ public class Interaction extends AbstractInteraction<Interaction>
                 duplicate = payload.duplicate();
             }
             transportFrame = new TransportFrame(channel.shortValue(), frameBody, duplicate);
-            ListenableFuture<Void> listenableFuture = sendPerformativeAndChainFuture(transportFrame);
+            CompletableFuture<Void> listenableFuture = sendPerformativeAndChainFuture(transportFrame);
             if (frameBody instanceof Transfer)
             {
-                listenableFuture.addListener(() -> ((Transfer) frameBody).dispose(), MoreExecutors.directExecutor());
+                listenableFuture.whenComplete((result, error) -> ((Transfer) frameBody).dispose());
             }
             if (duplicate != null)
             {
-                listenableFuture.addListener(() -> duplicate.dispose(), MoreExecutors.directExecutor());
+                listenableFuture.whenComplete((result, error) -> duplicate.dispose());
             }
         }
     }
diff --git a/systests/protocol-tests-amqp-1-0/src/test/java/org/apache/qpid/tests/protocol/v1_0/messaging/DeleteOnCloseTest.java b/systests/protocol-tests-amqp-1-0/src/test/java/org/apache/qpid/tests/protocol/v1_0/messaging/DeleteOnCloseTest.java
index cf07966ac4..987ff93400 100644
--- a/systests/protocol-tests-amqp-1-0/src/test/java/org/apache/qpid/tests/protocol/v1_0/messaging/DeleteOnCloseTest.java
+++ b/systests/protocol-tests-amqp-1-0/src/test/java/org/apache/qpid/tests/protocol/v1_0/messaging/DeleteOnCloseTest.java
@@ -27,9 +27,9 @@ import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.junit.jupiter.api.Test;
 
 import org.apache.qpid.server.protocol.v1_0.Session_1_0;
@@ -195,7 +195,7 @@ public class DeleteOnCloseTest extends BrokerAdminUsingTestBase
             assertThat(Utils.doesNodeExist(getBrokerAdmin(), newTempQueueAddress), is(true));
         }
 
-        final ListenableFuture<Void> restart = getBrokerAdmin().restart();
+        final CompletableFuture<Void> restart = getBrokerAdmin().restart();
         restart.get(BrokerAdmin.RESTART_TIMEOUT, TimeUnit.MILLISECONDS);
         assertThat(Utils.doesNodeExist(getBrokerAdmin(), newTempQueueAddress), is(true));
     }
diff --git a/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractFrameTransport.java b/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractFrameTransport.java
index 1722492a23..543206502b 100644
--- a/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractFrameTransport.java
+++ b/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractFrameTransport.java
@@ -19,6 +19,7 @@
 
 package org.apache.qpid.tests.protocol;
 
+import io.netty.util.concurrent.Future;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.instanceOf;
@@ -26,13 +27,12 @@ import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 
 import java.net.InetSocketAddress;
+import java.util.Objects;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
@@ -131,27 +131,31 @@ public abstract class AbstractFrameTransport<I extends AbstractInteraction<I>> i
         }
     }
 
-    ListenableFuture<Void> sendProtocolHeader(final byte[] bytes)
+    CompletableFuture<Void> sendProtocolHeader(final byte[] bytes)
     {
         return sendBytes(bytes);
     }
 
-    public ListenableFuture<Void> sendBytes(final byte[] bytes)
+    public CompletableFuture<Void> sendBytes(final byte[] bytes)
     {
-        Preconditions.checkState(_channel != null, "Not connected");
+        Objects.requireNonNull(_channel, "Not connected");
         final ChannelPromise promise = _channel.newPromise();
         final ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
         buffer.writeBytes(bytes);
         _channel.write(buffer, promise);
-        return JdkFutureAdapters.listenInPoolThread(promise);
+        final CompletableFuture<Void> result = new CompletableFuture<>();
+        promise.addListener(future -> completeFuture(future, result));
+        return result;
     }
 
-    public ListenableFuture<Void> sendPerformative(final Object data) throws Exception
+    public CompletableFuture<Void> sendPerformative(final Object data) throws Exception
     {
-        Preconditions.checkState(_channel != null, "Not connected");
+        Objects.requireNonNull(_channel, "Not connected");
         final ChannelPromise promise = _channel.newPromise();
         _channel.write(data, promise);
-        return JdkFutureAdapters.listenInPoolThread(promise);
+        final CompletableFuture<Void> result = new CompletableFuture<>();
+        promise.addListener(future -> completeFuture(future, result));
+        return result;
     }
 
     <T extends Response<?>> T getNextResponse() throws Exception
@@ -176,6 +180,18 @@ public abstract class AbstractFrameTransport<I extends AbstractInteraction<I>> i
         _channel.flush();
     }
 
+    private static void completeFuture(Future<? super Void> future, CompletableFuture<Void> result)
+    {
+        if (future.isSuccess())
+        {
+            result.complete(null);
+        }
+        else
+        {
+            result.completeExceptionally(future.cause());
+        }
+    }
+
     public abstract byte[] getProtocolHeader();
 
     public abstract I newInteraction();
diff --git a/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractInteraction.java b/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractInteraction.java
index 0a86d8d0cd..2cc467565a 100644
--- a/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractInteraction.java
+++ b/systests/protocol-tests-core/src/main/java/org/apache/qpid/tests/protocol/AbstractInteraction.java
@@ -20,21 +20,18 @@
  */
 package org.apache.qpid.tests.protocol;
 
-import static com.google.common.util.concurrent.Futures.allAsList;
-
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 public abstract class AbstractInteraction<I extends AbstractInteraction<I>>
 {
     private final AbstractFrameTransport<I> _transport;
-    private ListenableFuture<?> _latestFuture;
+    private CompletableFuture<?> _latestFuture;
     private Response<?> _latestResponse;
 
     public AbstractInteraction(final AbstractFrameTransport<I> frameTransport)
@@ -131,31 +128,17 @@ public abstract class AbstractInteraction<I extends AbstractInteraction<I>>
         return (T) _latestResponse.getBody();
     }
 
-    protected ListenableFuture<Void> sendPerformativeAndChainFuture(final Object frameBody) throws Exception
+    protected CompletableFuture<Void> sendPerformativeAndChainFuture(final Object frameBody) throws Exception
     {
-        final ListenableFuture<Void> future = _transport.sendPerformative(frameBody);
-        if (_latestFuture != null)
-        {
-            _latestFuture = allAsList(_latestFuture, future);
-        }
-        else
-        {
-            _latestFuture = future;
-        }
+        final CompletableFuture<Void> future = _transport.sendPerformative(frameBody);
+        _latestFuture = _latestFuture != null ? CompletableFuture.allOf(_latestFuture, future) : future;
         return future;
     }
 
     public I negotiateProtocol() throws Exception
     {
-        final ListenableFuture<Void> future = _transport.sendProtocolHeader(getProtocolHeader());
-        if (_latestFuture != null)
-        {
-            _latestFuture = allAsList(_latestFuture, future);
-        }
-        else
-        {
-            _latestFuture = future;
-        }
+        final CompletableFuture<Void> future = _transport.sendProtocolHeader(getProtocolHeader());
+        _latestFuture = _latestFuture != null ? CompletableFuture.allOf(_latestFuture, future) : future;
         return getInteraction();
     }
 
diff --git a/systests/qpid-systests-spawn-admin/src/main/java/org/apache/qpid/systests/admin/SpawnBrokerAdmin.java b/systests/qpid-systests-spawn-admin/src/main/java/org/apache/qpid/systests/admin/SpawnBrokerAdmin.java
index 4f538382c6..96b7cf006b 100644
--- a/systests/qpid-systests-spawn-admin/src/main/java/org/apache/qpid/systests/admin/SpawnBrokerAdmin.java
+++ b/systests/qpid-systests-spawn-admin/src/main/java/org/apache/qpid/systests/admin/SpawnBrokerAdmin.java
@@ -46,6 +46,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -63,8 +64,6 @@ import javax.naming.NamingException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.io.ByteStreams;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -244,11 +243,11 @@ public class SpawnBrokerAdmin implements BrokerAdmin, Closeable
     }
 
     @Override
-    public ListenableFuture<Void> restart()
+    public CompletableFuture<Void> restart()
     {
         stop();
         start();
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/BrokerAdmin.java b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/BrokerAdmin.java
index 900738e1eb..9d87b4c06f 100644
--- a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/BrokerAdmin.java
+++ b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/BrokerAdmin.java
@@ -22,8 +22,7 @@ package org.apache.qpid.tests.utils;
 
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
-
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.qpid.server.plugin.Pluggable;
 
@@ -46,7 +45,7 @@ public interface BrokerAdmin extends Pluggable
     int getQueueDepthMessages(String testQueueName);
 
     boolean supportsRestart();
-    ListenableFuture<Void> restart();
+    CompletableFuture<Void> restart();
 
     boolean isAnonymousSupported();
     boolean isSASLSupported();
diff --git a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/EmbeddedBrokerPerClassAdminImpl.java b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/EmbeddedBrokerPerClassAdminImpl.java
index c995b3ac02..070fcd80a6 100644
--- a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/EmbeddedBrokerPerClassAdminImpl.java
+++ b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/EmbeddedBrokerPerClassAdminImpl.java
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
@@ -47,8 +48,6 @@ import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 import javax.security.auth.Subject;
 
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -369,7 +368,7 @@ public class EmbeddedBrokerPerClassAdminImpl implements BrokerAdmin
     }
 
     @Override
-    public ListenableFuture<Void> restart()
+    public CompletableFuture<Void> restart()
     {
         try
         {
@@ -381,9 +380,9 @@ public class EmbeddedBrokerPerClassAdminImpl implements BrokerAdmin
         }
         catch (Exception e)
         {
-            return Futures.immediateFailedFuture(e);
+            return CompletableFuture.failedFuture(e);
         }
-        return Futures.immediateFuture(null);
+        return CompletableFuture.completedFuture(null);
     }
 
     @Override
diff --git a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/ExternalQpidBrokerAdminImpl.java b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/ExternalQpidBrokerAdminImpl.java
index 17f18909d7..d0e2f5807a 100644
--- a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/ExternalQpidBrokerAdminImpl.java
+++ b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/ExternalQpidBrokerAdminImpl.java
@@ -25,8 +25,8 @@ import java.net.InetSocketAddress;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -133,7 +133,7 @@ public class ExternalQpidBrokerAdminImpl implements BrokerAdmin
     }
 
     @Override
-    public ListenableFuture<Void> restart()
+    public CompletableFuture<Void> restart()
     {
         throw new UnsupportedOperationException("External Qpid Broker does not support restart.");
     }
diff --git a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/LoggingBrokerAdminDecorator.java b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/LoggingBrokerAdminDecorator.java
index f432d2867a..7fa3d33c6e 100644
--- a/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/LoggingBrokerAdminDecorator.java
+++ b/systests/systests-utils/src/main/java/org/apache/qpid/tests/utils/LoggingBrokerAdminDecorator.java
@@ -22,9 +22,9 @@ package org.apache.qpid.tests.utils;
 
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
+import java.util.concurrent.CompletableFuture;
 
 import ch.qos.logback.classic.LoggerContext;
-import com.google.common.util.concurrent.ListenableFuture;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -121,7 +121,7 @@ public class LoggingBrokerAdminDecorator implements BrokerAdmin
     }
 
     @Override
-    public ListenableFuture<Void> restart()
+    public CompletableFuture<Void> restart()
     {
         return _delegate.restart();
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org