All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.portal.events.GlobalShutdownAction Maven / Gradle / Ivy

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.events;

import com.liferay.document.library.kernel.document.conversion.DocumentConversionUtil;
import com.liferay.petra.executor.PortalExecutorManager;
import com.liferay.petra.lang.CentralizedThreadLocal;
import com.liferay.portal.kernel.dao.db.DB;
import com.liferay.portal.kernel.dao.db.DBManagerUtil;
import com.liferay.portal.kernel.dao.db.DBType;
import com.liferay.portal.kernel.dao.jdbc.DataAccess;
import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
import com.liferay.portal.kernel.events.SimpleAction;
import com.liferay.portal.kernel.log.Jdk14LogFactoryImpl;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.ServiceProxyFactory;
import com.liferay.portal.struts.AuthPublicPathRegistry;
import com.liferay.portal.util.PropsUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.util.ThirdPartyThreadLocalRegistry;

import java.sql.Connection;
import java.sql.Statement;

/**
 * @author Brian Wing Shun Chan
 */
public class GlobalShutdownAction extends SimpleAction {

	@Override
	public void run(String[] ids) {

		// Lower shutdown levels have dependences on higher levels, therefore
		// lower ones need to shutdown before higher ones. Components within the
		// same shutdown level should not depend on each other.

		shutdownLevel1();
		shutdownLevel2();
		shutdownLevel3();
		shutdownLevel4();
		shutdownLevel5();
		shutdownLevel6();
		shutdownLevel7();
	}

	protected ThreadGroup getThreadGroup() {
		Thread currentThread = Thread.currentThread();

		ThreadGroup threadGroup = currentThread.getThreadGroup();

		for (int i = 0; i < 10; i++) {
			if (threadGroup.getParent() == null) {
				break;
			}

			threadGroup = threadGroup.getParent();
		}

		return threadGroup;
	}

	protected Thread[] getThreads(ThreadGroup threadGroup) {
		Thread[] threads = new Thread[threadGroup.activeCount() * 2];

		threadGroup.enumerate(threads);

		return threads;
	}

	protected void shutdownLevel1() {

		// Authentication

		AuthPublicPathRegistry.unregister(PropsValues.AUTH_PUBLIC_PATHS);

		// OpenOffice

		DocumentConversionUtil.disconnect();
	}

	protected void shutdownLevel2() {

		// Auto deploy

		AutoDeployUtil.unregisterDir(AutoDeployDir.DEFAULT_NAME);

		// Hot deploy

		HotDeployUtil.unregisterListeners();
	}

	protected void shutdownLevel3() {

		// Messaging

		MessageBusUtil.shutdown(true);
	}

	protected void shutdownLevel4() {

		// Hypersonic

		DB db = DBManagerUtil.getDB();

		if (db.getDBType() == DBType.HYPERSONIC) {
			try (Connection connection = DataAccess.getConnection();
				Statement statement = connection.createStatement()) {

				statement.executeUpdate("SHUTDOWN");
			}
			catch (Exception exception) {
				_log.error(exception);
			}
		}
	}

	protected void shutdownLevel5() {

		// Portal executors

		_portalExecutorManager.shutdown(true);
	}

	protected void shutdownLevel6() {

		// Reset log to default JDK 1.4 logger. This will allow WARs dependent
		// on the portal to still log events after the portal WAR has been
		// destroyed.

		try {
			LogFactoryUtil.setLogFactory(new Jdk14LogFactoryImpl());
		}
		catch (Exception exception) {
			if (_log.isDebugEnabled()) {
				_log.debug(exception);
			}
		}

		// Thread local registry

		ThirdPartyThreadLocalRegistry.resetThreadLocals();
		CentralizedThreadLocal.clearShortLivedThreadLocals();
	}

	protected void shutdownLevel7() {

		// Programmatically exit

		if (GetterUtil.getBoolean(
				PropsUtil.get(PropsKeys.SHUTDOWN_PROGRAMMATICALLY_EXIT))) {

			Thread currentThread = Thread.currentThread();

			ThreadGroup threadGroup = getThreadGroup();

			Thread[] threads = getThreads(threadGroup);

			for (Thread thread : threads) {
				if ((thread == null) || (thread == currentThread)) {
					continue;
				}

				try {
					thread.interrupt();
				}
				catch (Exception exception) {
					if (_log.isDebugEnabled()) {
						_log.debug(exception);
					}
				}
			}

			threadGroup.destroy();
		}
	}

	private static final Log _log = LogFactoryUtil.getLog(
		GlobalShutdownAction.class);

	private static volatile PortalExecutorManager _portalExecutorManager =
		ServiceProxyFactory.newServiceTrackedInstance(
			PortalExecutorManager.class, GlobalShutdownAction.class,
			"_portalExecutorManager", true);

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy