private void stop()

in artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java [1260:1563]


   private void stop(boolean failoverOnServerShutdown,
                     final boolean criticalIOError,
                     boolean shutdownExternalComponents,
                     boolean restarting,
                     boolean isShutdown) {
      logger.debug("Stopping server {}", this);

      synchronized (this) {
         if (state == SERVER_STATE.STOPPED || state == SERVER_STATE.STOPPING) {
            return;
         }
         state = SERVER_STATE.STOPPING;

         ServerStatus.stopping(this);

         callPreDeActiveCallbacks();

         if (criticalIOError) {
            final ManagementService managementService = this.managementService;
            if (managementService != null) {
               // notifications trigger disk IO so we don't want to send any on a critical IO error
               managementService.enableNotifications(false);
            }
         }

         final FileStoreMonitor fileStoreMonitor = this.fileStoreMonitor;
         if (fileStoreMonitor != null) {
            fileStoreMonitor.stop();
            this.fileStoreMonitor = null;
         }

         if (failoverOnServerShutdown) {
            final Activation activation = this.activation;
            if (activation != null) {
               activation.sendPrimaryIsStopping();
            }
         }

         stopComponent(connectionRouterManager);

         stopComponent(connectorsService);

         // we stop the groupingHandler before we stop the cluster manager so binding mappings
         // aren't removed in case of failover
         if (groupingHandler != null) {
            managementService.removeNotificationListener(groupingHandler);
            stopComponent(groupingHandler);
         }
         stopComponent(federationManager);
         stopComponent(clusterManager);

         for (ActiveMQComponent component : this.protocolServices) {
            stopComponent(component);
         }
         protocolServices.clear();

         final RemotingService remotingService = this.remotingService;
         if (remotingService != null) {
            remotingService.pauseAcceptors();
         }

         // allows for graceful shutdown
         if (remotingService != null && configuration.isGracefulShutdownEnabled()) {
            long timeout = configuration.getGracefulShutdownTimeout();
            try {
               if (timeout == -1) {
                  remotingService.getConnectionCountLatch().await();
               } else {
                  remotingService.getConnectionCountLatch().await(timeout);
               }
            } catch (InterruptedException e) {
               ActiveMQServerLogger.LOGGER.interruptWhilstStoppingComponent(remotingService.getClass().getName());
            }
         }

         freezeConnections();
      }

      final Activation activation = this.activation;
      if (activation != null) {
         activation.postConnectionFreeze();
      }

      closeAllServerSessions(criticalIOError);

      // *************************************************************************************************************
      // There's no need to sync this part of the method, since the state stopped | stopping is checked within the sync
      //
      // we can't synchronized the whole method here as that would cause a deadlock
      // so stop is checking for stopped || stopping inside the lock
      // which will be already enough to guarantee that no other thread will be accessing this method here.
      //
      // *************************************************************************************************************

      final StorageManager storageManager = this.storageManager;
      if (storageManager != null)
         storageManager.clearContext();

      //before we stop any components deactivate any callbacks
      callDeActiveCallbacks();

      stopComponent(backupManager);

      if (activation != null) {
         try {
            activation.preStorageClose();
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(activation.getClass().getName(), t);
         }
      }

      final RemotingService remotingService = this.remotingService;

      if (remotingService != null) {
         // The notification must be sent with the StorageManager still up
         // this is because NotificationService will use storageManager.generateID
         remotingService.notifyStop();
      }

      // We start the preparation for the broker shutdown by first stopping acceptors, and removing connections
      // this is to avoid Exceptions while the broker is stopping as much as possible
      // by first stopping any pending connections before stopping the storage.
      // if we stopped the journal first before remoting we could have more exceptions being sent for the client.
      try {
         if (remotingService != null) {
            // it will close all connections except to the one used by replication
            remotingService.prepareStop(criticalIOError,  storageManager != null ? storageManager.getUsedConnections() : Collections.emptySet());
         }
      } catch (Throwable t) {
         ActiveMQServerLogger.LOGGER.errorStoppingComponent(remotingService.getClass().getName(), t);
      }

      stopComponent(pagingManager);

      if (!criticalIOError && pagingManager != null) {
         pagingManager.counterSnapshot();
      }

      final ManagementService managementService = this.managementService;

      // we have to disable management service before stopping the storage
      // otherwise management would send notifications eventually
      if (managementService != null) {
         try {
            managementService.enableNotifications(false);
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(managementService.getClass().getName(), t);
         }
      }

      if (storageManager != null) {
         try {
            storageManager.stop(criticalIOError, failoverOnServerShutdown);
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(storageManager.getClass().getName(), t);
         }
      }

      // We stop remotingService before otherwise we may lock the system in case of a critical IO
      // error shutdown
      if (remotingService != null) {
         try {
            remotingService.stop(criticalIOError);
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(remotingService.getClass().getName(), t);
         }
      }

      // Stop the management service after the remoting service to ensure all acceptors are deregistered with JMX
      if (managementService != null) {
         try {
            managementService.unregisterServer();
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(managementService.getClass().getName(), t);
         }
      }

      stopComponent(managementService);
      stopComponent(resourceManager);
      stopComponent(postOffice);

      if (scheduledPool != null && !scheduledPoolSupplied) {
         // we just interrupt all running tasks, these are supposed to be pings and the like.
         scheduledPool.shutdownNow();
      }

      stopComponent(memoryManager);

      for (SecuritySettingPlugin securitySettingPlugin : configuration.getSecuritySettingPlugins()) {
         securitySettingPlugin.stop();
      }

      if (ioExecutorPool != null) {
         shutdownPool(ioExecutorPool);
      }

      if (pageExecutorPool != null) {
         shutdownPool(pageExecutorPool);
      }

      if (!scheduledPoolSupplied)
         scheduledPool = null;

      if (securityStore != null) {
         try {
            securityStore.stop();
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(securityStore.getClass().getName(), t);
         }
      }

      installMirrorController(null);

      pagingManager = null;
      securityStore = null;
      resourceManager = null;
      postOffice = null;
      queueFactory = null;
      resourceManager = null;
      messagingServerControl = null;
      memoryManager = null;
      backupManager = null;
      extraRecordsLoader = null;
      this.storageManager = null;

      sessions.clear();

      state = SERVER_STATE.STOPPED;

      activationLatch.setCount(1);

      // to display in the log message
      SimpleString tempNodeID = getNodeID();
      if (activation != null) {
         try {
            activation.close(failoverOnServerShutdown, restarting);
         } catch (Throwable t) {
            ActiveMQServerLogger.LOGGER.errorStoppingComponent(activation.getClass().getName(), t);
         }
      }

      // JDBC journal can use this thread pool to configure the network timeout on a pooled connection:
      // better to stop it after closing activation (and JDBC node manager on it)
      final ExecutorService threadPool = this.threadPool;
      if (threadPool != null && !threadPoolSupplied) {
         shutdownPool(threadPool);
      }
      if (!threadPoolSupplied) {
         this.threadPool = null;
      }

      // given that threadPool can be garbage collected, need to clear anything that would make it leaks
      clearJdbcNetworkTimeout();

      if (activationThread != null) {
         try {
            activationThread.join(30000);
         } catch (InterruptedException e) {
            ActiveMQServerLogger.LOGGER.interruptWhilstStoppingComponent(activationThread.getClass().getName());
         }

         if (activationThread.isAlive()) {
            ActiveMQServerLogger.LOGGER.activationDidntFinish(this);
            activationThread.interrupt();
         }
      }

      stopComponent(nodeManager);

      nodeManager = null;

      addressSettingsRepository.clearListeners();

      addressSettingsRepository.clearCache();

      scaledDownNodeIDs.clear();

      connectedClientIds.clear();

      stopExternalComponents(shutdownExternalComponents);

      try {
         this.analyzer.clear();
         this.analyzer.stop();
      } catch (Exception e) {
         logger.warn(e.getMessage(), e);
      } finally {
         this.analyzer = null;
      }

      for (ActivateCallback callback: activateCallbacks) {
         if (isShutdown) {
            callback.shutdown(this);
         } else {
            callback.stop(this);
         }
      }

      if (identity != null) {
         ActiveMQServerLogger.LOGGER.serverStopped("identity=" + identity + ",version=" + getVersion().getFullVersion(), tempNodeID, getUptime());
      } else {
         ActiveMQServerLogger.LOGGER.serverStopped(getVersion().getFullVersion(), tempNodeID, getUptime());
      }
   }