private void shutdownServer() {
        shuttingDown = true;

        if (terminatorTimer != null) {
            terminatorTimer.cancel();
        }

        ClusterManager.shutdown();
        // Notify server listeners that the server is about to be stopped
        for (XMPPServerListener listener : listeners) {
            try {
                listener.serverStopping();
            } catch (Exception ex) {
                logger.error("Exception during listener shutdown", ex);
            }
        }
        // If we don't have modules then the server has already been shutdown
        if (modules.isEmpty()) {
            return;
        }

        // Stop all plugins
        logger.info("Shutting down plugins ...");
        if (pluginManager != null) {
            try {
                pluginManager.shutdown();
            } catch (Exception ex) {
                logger.error("Exception during plugin shutdown", ex);
            }
        }

        logger.info("Shutting down " + modules.size() + " modules ...");

        final SimpleTimeLimiter timeLimiter = SimpleTimeLimiter.create( Executors.newSingleThreadExecutor(
            new ThreadFactoryBuilder()
                .setDaemon( true )
                .setNameFormat( "shutdown-thread-%d" )
                .build() ) );

        // OF-1996" Get all modules and stop and destroy them. Do this in the reverse order in which the were created.
        // This ensures that the 'most important' / core modules are shut down last, giving other modules the
        // opportunity to make use of their functionality during their shutdown (eg: MUC wants to send messages during
        // shutdown).
        final List<Class<Module>> reverseInsertionOrder = new ArrayList<>( modules.keySet() );
        Collections.reverse( reverseInsertionOrder );

        for( final Class<Module> moduleClass : reverseInsertionOrder ) {
            final Module module = modules.get( moduleClass );
            try {
                // OF-1607: Apply a configurable timeout to the duration of stop/destroy invocation.
                timeLimiter.runWithTimeout(() -> stopAndDestroyModule(module), JiveGlobals.getLongProperty("shutdown.modules.timeout-millis", Long.MAX_VALUE), TimeUnit.MILLISECONDS);
            } catch ( Exception e ) {
                logger.warn("An exception occurred while stopping / destroying module '{}'.", module.getName(), e);
                System.err.println(e);
            }
        }

        modules.clear();
        // Stop the Db connection manager.
        try {	
            DbConnectionManager.destroyConnectionProvider();
        } catch (Exception ex) {
            logger.error("Exception during DB shutdown", ex);
        }

        // Shutdown the task engine.
        TaskEngine.getInstance().shutdown();

        // hack to allow safe stopping
        logger.info("Openfire stopped");

        // Shut down the logging framework (causing the last few log entries to be flushed)
        LogManager.shutdown();
    }
Makes a best effort attempt to shutdown the server
xmppserver/src/main/java/org/jivesoftware/openfire/XMPPServer.java